F # - interfejsy
Interfejsy zapewniają abstrakcyjny sposób zapisywania szczegółów implementacji klasy. Jest to szablon, który deklaruje metody, które klasa musi zaimplementować i ujawnić publicznie.
Składnia
Interfejs określa zestawy powiązanych elementów, które implementują inne klasy. Ma następującą składnię -
// 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
Uwaga -
W deklaracji interfejsu członkowie nie są zaimplementowani.
Członkowie są abstrakcyjni, zadeklarowani przez abstractsłowo kluczowe. Możesz jednak podać domyślną implementację przy użyciudefault słowo kluczowe.
Interfejsy można implementować za pomocą wyrażeń obiektów lub typów klas.
W implementacji klas lub obiektów musisz dostarczyć treści metod dla abstrakcyjnych metod interfejsu.
Słowa kluczowe interface i end, które oznaczają początek i koniec definicji, są opcjonalne.
Na przykład,
type IPerson =
abstract Name : string
abstract Enter : unit -> unit
abstract Leave : unit -> unit
Wywołanie metod interfejsu
Metody interfejsu są wywoływane za pośrednictwem interfejsu, a nie przez wystąpienie klasy lub typu implementującego interfejs. Aby wywołać metodę interfejsu, należy przesłać rzutowanie do typu interfejsu przy użyciu:> operator (operator upcast).
Na przykład,
(s :> IPerson).Enter()
(s :> IPerson).Leave()
Poniższy przykład ilustruje koncepcję -
Przykład
type IPerson =
abstract Name : string
abstract Enter : unit -> unit
abstract Leave : unit -> unit
type Student(name : string, id : int) =
member this.ID = id
interface IPerson with
member this.Name = name
member this.Enter() = printfn "Student entering premises!"
member this.Leave() = printfn "Student leaving premises!"
type StuffMember(name : string, id : int, salary : float) =
let mutable _salary = salary
member this.Salary
with get() = _salary
and set(value) = _salary <- value
interface IPerson with
member this.Name = name
member this.Enter() = printfn "Stuff member entering premises!"
member this.Leave() = printfn "Stuff member leaving premises!"
let s = new Student("Zara", 1234)
let st = new StuffMember("Rohit", 34, 50000.0)
(s :> IPerson).Enter()
(s :> IPerson).Leave()
(st :> IPerson).Enter()
(st :> IPerson).Leave()
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
Student entering premises!
Student leaving premises!
Stuff member entering premises!
Stuff member leaving premises!
Dziedziczenie interfejsu
Interfejsy mogą dziedziczyć z jednego lub więcej interfejsów podstawowych.
Poniższy przykład przedstawia koncepcję -
type Interface1 =
abstract member doubleIt: int -> int
type Interface2 =
abstract member tripleIt: int -> int
type Interface3 =
inherit Interface1
inherit Interface2
abstract member printIt: int -> string
type multiplierClass() =
interface Interface3 with
member this.doubleIt(a) = 2 * a
member this.tripleIt(a) = 3 * a
member this.printIt(a) = a.ToString()
let ml = multiplierClass()
printfn "%d" ((ml:>Interface3).doubleIt(5))
printfn "%d" ((ml:>Interface3).tripleIt(5))
printfn "%s" ((ml:>Interface3).printIt(5))
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
10
15
5