Dziedziczenie (F#)
Dziedziczenie jest używana do modelowania relacji "jest a" lub subtyping w programowaniu obiektowym.
Określanie relacji dziedziczenia
Określić relacje dziedziczenia przy użyciu inherit słowa kluczowego w deklaracji klasy.Podstawowe syntaktycznych formularza znajduje się w następującym przykładzie.
type MyDerived(...) =
inherit MyBase(...)
Klasa może mieć co najwyżej jeden bezpośrednia klasa podstawowa.Jeśli klasa podstawowa nie należy określać przy użyciu inherit słowa kluczowego, klasa dziedziczy niejawnie z Object.
Elementy dziedziczone
Jeśli klasa dziedziczy z innej klasy, metody i członkowie klasy podstawowej są dostępne dla użytkowników w klasie pochodnej tak, jakby były one bezpośredni członkowie klasy pochodne.
Dowolne let powiązania i parametry konstruktora są prywatne do klasy i, w związku z tym, nie jest dostępny z klas pochodnych.
Słowo kluczowe base jest dostępny w klas pochodnych i odnosi się do instancji klasy bazowej.Jest ono używane, takich jak self-identifier.
Wirtualne metody i przesłonięcia
Metod wirtualnych (i właściwości) działa nieco inaczej w F# w porównaniu do innych.Języki netto.Aby zadeklarować nowym członkiem wirtualnym, należy użyć abstract słowa kluczowego.Aby to zrobić niezależnie od tego, czy dostarczyć domyślna Implementacja tej metody.Ten sposób pełną definicję wirtualnego metody w klasie bazowej następujące tego wzorca:
abstractmembermethod-name : type
defaultself-identifier.method-nameargument-list = method-body
I w klasie pochodnej przesłonięcie to metoda wirtualna następuje tego wzorca:
overrideself-identifier.method-nameargument-list = method-body
Jeżeli pominięto Domyślna implementacja w klasie bazowej, klasy bazowej staje się klasy abstrakcyjnej.
Poniższy przykład kodu ilustruje deklarację metodą wirtualną function1 w klasie podstawowej i sposobu zastąpienia go w klasie pochodnej.
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
Konstruktory i dziedziczenie
Należy wywołać konstruktora klasy podstawowej w klasie pochodnej.Argumenty konstruktora klasy podstawowej są wyświetlane na liście argumentów w inherit klauzuli.Należy określić wartości, które są używane w argumentach dostarczonych do konstruktora klasy pochodnej.
Poniższy kod ilustruje klasy podstawowej i klasy pochodne, gdzie w klasie pochodnej wywołania konstruktora klasy podstawowej w klauzuli dziedziczenia:
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
W odniesieniu do wielu konstruktory następujący kod może być używany.Pierwszy wiersz konstruktorów klas pochodnych jest inherit klauzuli i pola są wyświetlane jako wyraźne pól, które są zgłoszone jako val słowa kluczowego.Aby uzyskać więcej informacji, zobacz pól jawne: val słowa kluczowego.
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")
Rozwiązania alternatywne do dziedziczenia
W przypadkach gdy wymagane jest niewielkich modyfikacji typu należy wziąć pod uwagę przy użyciu wyrażenia obiektu jako alternatywa dla dziedziczenia.Poniższy przykład ilustruje użycie wyrażenia obiektu, jako alternatywę dla tworzenia nowego typu pochodnego:
open System
let object1 = { new Object() with
override this.ToString() = "This overrides object.ToString()"
}
printfn "%s" (object1.ToString())
Aby uzyskać więcej informacji o wyrażeniach obiektu, zobacz Wyrażenia obiektów (F#).
Tworząc obiekt hierarchii, należy rozważyć użycie dyskryminowanych Unii nad dziedziczeniem.Związki dyskryminowanych może również zachowanie modelu zróżnicowana w różnych obiektów, które współużytkują wspólną typ ogólny.Pojedynczy Unii dyskryminowanych często można wyeliminować potrzebę liczba klas pochodnych, które są niewielkich zmian.Informacje o dyskryminowanych związków, zobacz Sumy rozłączne (F#).