F # - Interfaces
Las interfaces proporcionan una forma abstracta de escribir los detalles de implementación de una clase. Es una plantilla que declara los métodos que la clase debe implementar y exponer públicamente.
Sintaxis
Una interfaz especifica los conjuntos de miembros relacionados que implementan otras clases. Tiene la siguiente sintaxis:
// 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
Tenga en cuenta:
En una declaración de interfaz, los miembros no se implementan.
Los miembros son abstractos, declarados por el abstractpalabra clave. Sin embargo, puede proporcionar una implementación predeterminada utilizando eldefault palabra clave.
Puede implementar interfaces usando expresiones de objeto o usando tipos de clases.
En la implementación de clase u objeto, debe proporcionar cuerpos de método para métodos abstractos de la interfaz.
Las palabras clave interface y end, que marcan el inicio y el final de la definición, son opcionales.
Por ejemplo,
type IPerson =
abstract Name : string
abstract Enter : unit -> unit
abstract Leave : unit -> unit
Métodos de interfaz de llamada
Los métodos de interfaz se llaman a través de la interfaz, no a través de la instancia de la clase o tipo de interfaz de implementación. Para llamar a un método de interfaz, puede convertir el tipo de interfaz utilizando el:> operador (operador upcast).
Por ejemplo,
(s :> IPerson).Enter()
(s :> IPerson).Leave()
El siguiente ejemplo ilustra el concepto:
Ejemplo
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()
Cuando compila y ejecuta el programa, produce el siguiente resultado:
Student entering premises!
Student leaving premises!
Stuff member entering premises!
Stuff member leaving premises!
Herencia de la interfaz
Las interfaces pueden heredar de una o más interfaces base.
El siguiente ejemplo muestra el concepto:
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))
Cuando compila y ejecuta el programa, produce el siguiente resultado:
10
15
5