Vererbung (F#)

Aktualisiert: September 2010

Vererbung wird in der objektorientierten Programmierung verwendet, um die Ist-Beziehung bzw. die Definition von Untertypen zu modellieren.

Angeben von Vererbungsbeziehungen

Vererbungsbeziehungen werden in einer Klassendeklaration mit dem inherit-Schlüsselwort angegeben. Die grundlegende syntaktische Form wird im folgenden Beispiel gezeigt.

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

Eine Klasse kann über höchstens eine direkte Basisklasse verfügen. Wenn Sie keine Basisklasse mit dem inherit-Schlüsselwort angeben, erbt die Klasse implizit von Object.

Geerbte Member

Wenn eine Klasse von einer anderen Klasse erbt, sind die Methoden und Member der Basisklasse für Benutzer der abgeleiteten Klasse wie direkte Member der abgeleiteten Klasse verfügbar.

let-Bindungen und Konstruktorparameter sind private Member einer Klasse, daher kann nicht aus abgeleiteten Klassen auf sie zugegriffen werden.

Das Schlüsselwort base, das auf die Basisklasseninstanz verweist, ist in abgeleiteten Klassen verfügbar. Es wird wie der Selbstbezeichner verwendet.

Virtuelle Methoden und Überschreibungen

Die Funktionsweise virtueller Methoden (und Eigenschaften) in F# unterscheidet sich von der Funktionsweise in anderen .NET-Sprachen. Sie deklarieren einen neuen virtuellen Member mithilfe des abstract-Schlüsselworts. Die Deklaration erfolgt unabhängig davon, ob Sie eine Standardimplementierung für die Methode bereitstellen. Somit entspricht die vollständige Definition einer virtuellen Methode in einer Basisklasse dem folgenden Muster:

abstract member method-name : type

default self-identifier.method-name argument-list = method-body

In einer abgeleiteten Klasse entspricht eine Überschreibung der virtuellen Methode dem folgenden Muster:

override self-identifier.method-name argument-list = method-body

Wenn Sie die Standardimplementierung in der Basisklasse weglassen, wird aus der Basisklasse eine abstrakte Klasse.

Im folgenden Codebeispiel werden die Deklaration der neuen virtuellen Methode function1 in einer Basisklasse und das Überschreiben der Methode in einer abgeleiteten Klasse veranschaulicht.

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

Konstruktoren und Vererbung

Der Konstruktor für die Basisklasse muss in der abgeleiteten Klasse aufgerufen werden. Die Argumente für den Basisklassenkonstruktor sind in der Argumentliste der inherit-Klausel enthalten. Die verwendeten Werte müssen anhand der für den Konstruktor der abgeleiteten Klasse bereitgestellten Argumente bestimmt werden.

Im folgenden Code werden eine Basisklasse und eine abgeleitete Klasse veranschaulicht, wobei die abgeleitete Klasse den Basisklassenkonstruktor in der inherit-Klausel aufruft:

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

Bei mehreren Konstruktoren kann der folgende Code verwendet werden. Die erste Zeile der Konstruktoren der abgeleiteten Klasse ist die inherit-Klausel, und die Felder werden als explizite Felder angezeigt, die mit dem val-Schlüsselwort deklariert werden. Weitere Informationen finden Sie unter Explizite Felder: Das val-Schlüsselwort.

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")

Alternativen zur Vererbung

In Fällen, in denen eine geringfügige Änderung eines Typs erforderlich ist, empfiehlt sich möglicherweise Alternative zur Vererbung die Verwendung eines Objektausdrucks. Im folgenden Beispiel wird die Verwendung eines Objektausdrucks als Alternative zum Erstellen eines neuen abgeleiteten Typs veranschaulicht:

open System

let object1 = { new Object() with
      override this.ToString() = "This overrides object.ToString()"
      }

printfn "%s" (object1.ToString())

Weitere Informationen zu Objektausdrücken finden Sie unter Objektausdrücke (F#).

Wenn Sie Objekthierarchien erstellen, können Sie statt Vererbung eine Unterscheidungs-Union verwenden. Unterscheidungs-Unions können verschiedenartiges Verhalten unterschiedlicher Objekte modellieren, die einen gemeinsamen Gesamttyp aufweisen. Mit einer einzelnen Unterscheidungs-Union lassen sich häufig mehrere abgeleitete Klassen vermeiden, die sich geringfügig voneinander unterscheiden. Informationen zu Unterscheidungs-Unions finden Sie unter Unterscheidungs-Union (F#).

Siehe auch

Referenz

Objektausdrücke (F#)

Weitere Ressourcen

F#-Sprachreferenz

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

September 2010

Informationen und Codebeispiel für die Verwendung mehrerer Basisklassenkonstruktoren wurden hinzugefügt.

Informationsergänzung.