Schnittstellen (F#)

Schnittstellen geben Sätze von verwandten Membern an, die von anderen Klassen implementiert werden.

// Interface declaration:
[ attributes ]
type interface-name =
   [ interface ]
     [ inherit base-interface-name ...]
     abstract member1 : [ argument-types1 -> ] return-type1
     abstract member2 : [ argument-types2 -> ] return-type2
     ...
   [ end ]

// Implementing, inside a class type definition:
interface interface-name with
   member self-identifier.member1 argument-list = method-body1
   member self-identifier.member2 argument-list = method-body2

// Implementing, by using an object expression:
[ attributes ]
let class-name (argument-list) =
   { new interface-name with
       member self-identifier.member1 argument-list = method-body1
       member self-identifier.member2 argument-list = method-body2
       [ base-interface-definitions ]
   }
   member-list

Hinweise

Schnittstellendeklarationen ähneln Klassendeklarationen, mit dem Unterschied, dass keine Member implementiert werden. Stattdessen sind alle Member abstrakt, wie durch das Schlüsselwort abstract angegeben. Für abstrakte Methoden wird kein Methodentext bereitgestellt. Sie können jedoch eine Standardimplementierung bereitstellen, indem Sie außerdem eine eigene Definition des Members als Methode zusammen mit dem default-Schlüsselwort einschließen. Dies entspricht dem Erstellen einer virtuellen Methode in einer Basisklasse in anderen .NET-Sprachen. Eine solche virtuelle Methode kann in Klassen überschrieben werden, die die Schnittstelle implementieren.

Es gibt zwei Möglichkeiten, Schnittstellen zu implementieren: mit Objektausdrücken und mit Klassentypen. In beiden Fällen stellt der Klassentyp bzw. Objektausdruck den Methodentext für abstrakte Methoden der Schnittstelle bereit. Implementierungen sind für den jeweiligen Typ spezifisch, der die Schnittstelle implementiert. Daher können sich Schnittstellenmethoden für verschiedene Typen voneinander unterscheiden.

Die Schlüsselwörter interface und end, die den Anfang und das Ende der Definition markieren, sind optional, wenn Sie einfache Syntax verwenden. Wenn Sie diese Schlüsselwörter nicht verwenden, versucht der Compiler per Rückschluss abzuleiten, ob der Typ eine Klasse oder eine Schnittstelle ist, indem er die verwendeten Konstrukte analysiert. Wenn Sie einen Member definieren oder andere Klassensyntax verwenden, wird der Typ als Klasse interpretiert.

Im .NET-Codierungsstil beginnen alle Schnittstellen mit dem Großbuchstaben I.

Implementieren von Schnittstellen mit Klassentypen

Sie können eine oder mehrere Schnittstellen in einem Klassentyp implementieren, indem Sie das interface-Schlüsselwort, den Namen der Schnittstelle und das with-Schlüsselwort, gefolgt von den Schnittstellenmemberdefinitionen verwenden, wie im folgenden Code gezeigt.

type IPrintable =
   abstract member Print : unit -> unit

type SomeClass1(x: int, y: float) =
   interface IPrintable with
      member this.Print() = printfn "%d %f" x y

Schnittstellenimplementierungen werden geerbt. Abgeleitete Klassen müssen sie also nicht erneut implementieren.

Aufrufen von Schnittstellenmethoden

Schnittstellenmethoden können nur über die Schnittstelle, nicht über ein Objekt des Typs, der die Schnittstelle implementiert, aufgerufen werden. Daher müssen Sie möglicherweise mit dem Operator :> oder upcast eine Aufwärtsumwandlung in den Schnittstellentyp ausführen, um diese Methoden aufzurufen.

Wenn Sie über ein Objekt des Typs SomeClass verfügen, müssen Sie zum Aufrufen der Schnittstellenmethode den Typ des Objekts per Aufwärtsumwandlung in den Schnittstellentyp umwandeln, wie im folgenden Code gezeigt.

let x1 = new SomeClass1(1, 2.0)
(x1 :> IPrintable).Print()

Als Alternative kann eine Methode für das Objekt deklariert werden, die die Aufwärtsumwandlung ausführt und die Schnittstellenmethode aufruft, wie im folgenden Beispiel gezeigt.

type SomeClass2(x: int, y: float) =
   member this.Print() = (this :> IPrintable).Print()
   interface IPrintable with
      member this.Print() = printfn "%d %f" x y

let x2 = new SomeClass2(1, 2.0)
x2.Print()

Implementieren von Schnittstellen mit Objektausdrücken

Objektausdrücke bieten ein schnelles Verfahren zum Implementieren einer Schnittstelle. Sie sind hilfreich, wenn Sie keinen benannten Typ erstellen müssen und nur ein Objekt benötigen, das die Schnittstellenmethoden unterstützt, ohne zusätzliche Methoden. Ein Objektausdruck wird im folgenden Code veranschaulicht.

let makePrintable(x: int, y: float) =
    { new IPrintable with
              member this.Print() = printfn "%d %f" x y }
let x3 = makePrintable(1, 2.0) 
x3.Print()

Schnittstellenvererbung

Eine Schnittstelle kann von einer oder mehreren Basisschnittstellen erben.

type Interface1 =
    abstract member Method1 : int -> int

type Interface2 =
    abstract member Method2 : int -> int

type Interface3 =
    inherit Interface1
    inherit Interface2
    abstract member Method3 : int -> int

type MyClass() =
    interface Interface3 with
        member this.Method1(n) = 2 * n
        member this.Method2(n) = n + 100
        member this.Method3(n) = n / 10

Siehe auch

Referenz

Objektausdrücke (F#)

Klassen (F#)

Weitere Ressourcen

F#-Sprachreferenz

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

Durch Datum der Änderung ersetzen.

Informationen zur Schnittstellenvererbung wurden hinzugefügt.

Informationsergänzung.