継承 (F#)

継承は、"is-a" 関係 (サブタイプ) をモデル化するためにオブジェクト指向プログラミングで使用されます。

継承関係の指定

継承関係を指定するには、クラス宣言で inherit キーワードを使用します。基本的な構文の形式を次の例に示します。

type MyDerived(...) =
   inherit MyBase(...)

クラスが持つことができる直接基本クラスは 1 つまでです。inherit キーワードを使用して基本クラスを指定しない場合は、クラスが Object を暗黙で継承します。

継承されたメンバー

あるクラスが別のクラスを継承すると、その派生クラスのユーザーは、派生クラスの直接的なメンバーのように基本クラスのメソッドとメンバーを使用できます。

let 束縛とコンストラクターのパラメーターは、クラスに対してプライベートであるため、派生クラスからはアクセスできません。

派生クラスでは、base キーワードを使用して基本クラスのインスタンスを参照できます。このキーワードは自己識別子のように使用されます。

仮想メソッドとオーバーライド

F# の仮想メソッド (およびプロパティ) の機能は、他の .NET 言語と比較して多少異なります。新しい仮想メンバーを宣言するには、abstract キーワードを使用します。仮想メソッドの既定の実装を指定するかどうかにかかわらず、このキーワードを使用します。このため、基本クラスでの仮想メソッドの完全な定義は、次のパターンに従います。

abstractmembermethod-name : type

defaultself-identifier.method-nameargument-list = method-body

派生クラスでのこの仮想メソッドのオーバーライドは、次のパターンに従います。

overrideself-identifier.method-nameargument-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

コンストラクターが複数の場合は、次のコードを使用できます。派生クラスのコンストラクターの 1 行目は inherit 句であり、フィールドは val キーワードで宣言された明示的なフィールドとして表示されます。詳細については、「Explicit Fields: The val Keyword (明示的なフィールド: 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())

オブジェクト式の詳細については、「オブジェクト式 (F#)」を参照してください。

オブジェクト階層を作成する場合は、継承の代わりに判別共用体の使用を検討してください。各オブジェクトは共通の型全体を共有しますが、判別共用体では、オブジェクトの違いによるさまざまな動作をモデル化することもできます。単一の判別共用体を使用すると、ほとんどの場合、互いに少しずつ異なる派生クラスを数多く作成する必要がなくなります。判別共用体については、「判別共用体 (F#)」を参照してください。

参照

関連項目

オブジェクト式 (F#)

その他の技術情報

F# 言語リファレンス