継承は、オブジェクト指向プログラミングで "is-a" リレーションシップ (サブタイピング) をモデル化するために使用されます。
継承リレーションシップの指定
継承リレーションシップは、クラス宣言で inherit
キーワードを使用して指定します。 基本的な構文形式を次の例に示します。
type MyDerived(...) =
inherit MyBase(...)
クラスには、最大で 1 つの直接基底クラスを含めることができます。
inherit
キーワードを使用して基底クラスを指定しない場合、クラスは暗黙的にSystem.Object
から継承します。
継承されたメンバー
クラスが別のクラスから継承する場合、基底クラスのメソッドとメンバーは、派生クラスの直接メンバーであるかのように派生クラスのユーザーが使用できます。
let バインディングとコンストラクター パラメーターはクラスに対してプライベートであるため、派生クラスからアクセスすることはできません。
キーワード base
は派生クラスで使用でき、基底クラスのインスタンスを参照します。 自己識別子と同様に使用されます。
仮想メソッドとオーバーライド
仮想メソッド (およびプロパティ) は、F# では他の .NET 言語と比べて動作が若干異なります。 新しい仮想メンバーを宣言するには、 abstract
キーワードを使用します。 これは、そのメソッドの既定の実装を提供するかどうかに関係なく行います。 したがって、基底クラスの仮想メソッドの完全な定義は、次のパターンに従います。
abstract member [method-name] : [type]
default [self-identifier].[method-name] [argument-list] = [method-body]
派生クラスでは、この仮想メソッドのオーバーライドは次のパターンに従います。
override [self-identifier].[method-name] [argument-list] = [method-body]
基底クラスの既定の実装を省略すると、基底クラスは抽象クラスになります。
次のコード例は、基底クラスで function1
新しい仮想メソッドの宣言と、それを派生クラスでオーバーライドする方法を示しています。
type MyClassBase1() =
let mutable z = 0
abstract member function1: int -> int
default u.function1(a: int) =
z <- z + a
z
type MyClassDerived1() =
inherit MyClassBase1()
override u.function1(a: int) = a + 1
コンストラクターと継承
基底クラスのコンストラクターは、派生クラスで呼び出す必要があります。 基底クラスのコンストラクターの引数は、inherit
句の引数リストに表示されます。 使用される値は、派生クラス コンストラクターに指定された引数から決定する必要があります。
次のコードは、基底クラスと派生クラスを示しています。ここで、派生クラスは inherit 句の基底クラス コンストラクターを呼び出します。
type MyClassBase2(x: int) =
let mutable z = x * x
do
for i in 1..z do
printf "%d " i
type MyClassDerived2(y: int) =
inherit MyClassBase2(y * 2)
do
for i in 1..y do
printf "%d " i
複数のコンストラクターの場合は、次のコードを使用できます。 派生クラス コンストラクターの最初の行は inherit
句であり、フィールドは、 val
キーワードで宣言された明示的なフィールドとして表示されます。 詳細については、「 明示的なフィールド: val
キーワード」を参照してください。
type BaseClass =
val string1 : string
new (str) = { string1 = str }
new () = { string1 = "" }
type DerivedClass =
inherit BaseClass
val string2 : string
new (str1, str2) = { inherit BaseClass(str1); string2 = str2 }
new (str2) = { inherit BaseClass(); string2 = str2 }
let obj1 = DerivedClass("A", "B")
let obj2 = DerivedClass("A")
継承の代替手段
型の軽微な変更が必要な場合は、継承の代わりにオブジェクト式を使用することを検討してください。 次の例は、新しい派生型を作成する代わりにオブジェクト式を使用する方法を示しています。
open System
let object1 =
{ new Object() with
override this.ToString() = "This overrides object.ToString()" }
printfn "%s" (object1.ToString())
オブジェクト式の詳細については、「 オブジェクト式」を参照してください。
オブジェクト階層を作成する場合は、継承ではなく判別共用体を使用することを検討してください。 判別共用体は、共通の全体的な型を共有するさまざまなオブジェクトのさまざまな動作をモデル化することもできます。 1 つの判別共用体を使用すると、多くの場合、相互に小さなバリエーションである多くの派生クラスが不要になります。 判別共用体の詳細については、「判別 共用体」を参照してください。
こちらも参照ください
.NET