Interface
Syntaxe
Idem classe abstraite avec :
Que des membres abstraits, définis par leur signature
Sans l'attribut
[<AbstractClass>]
Avec l'attribut
[<Interface>]
de manière optionnelle
type [accessibility-modifier] interface-name =
abstract memberN : [ argument-typesN -> ] return-typeN
Le nom d'une interface commence par
I
pour suivre la convention .NETLes arguments des méthodes peuvent être nommés :
[<Interface>]
type IPrintable =
abstract member Print : format:string -> unit
On peut aussi utiliser la syntaxe verbeuse avec un bloc interface ... end
,
→ Non idiomatique sauf dans le cas d'une interface sans membre a.k.a marker interface.
type IMarker = interface end
Implémentation
2 manières d'implémenter une interface :
Dans un type (comme en C♯)
Dans une expression objet 📍
Dans un type
type IPrintable =
abstract member Print : unit -> unit
type Range = { Min: int; Max: int } with
interface IPrintable with
member this.Print() = printfn $"[{this.Min}..{this.Max}]"
Dans une expression objet
type IConsole =
abstract ReadLine : unit -> string
abstract WriteLine : string -> unit
let console =
{ new IConsole with
member this.ReadLine () = Console.ReadLine ()
member this.WriteLine line = printfn "%s" line }
Implémentation par défaut
F♯ 5.0 supporte les interfaces définissant des méthodes avec implémentations par défaut écrites en C♯ 8+ mais ne permet pas de les définir.
Une interface F♯ est explicite
Implémentation d'une interface en F♯ ≡ Implémentation explicite d'une interface en C♯
→ Les méthodes de l'interface ne sont consommables que par upcasting :
type IPrintable =
abstract member Print : unit -> unit
type Range = { Min: int; Max: int } with
interface IPrintable with
member this.Print() = printfn $"[{this.Min}..{this.Max}]"
let range = { Min = 1; Max = 5 }
(range :> IPrintable).Print() // Opérateur `:>` de upcast 📍
// [1..5]
Implémenter une interface générique
type IValue<'T> =
abstract member Get : unit -> 'T
type BiValue() =
interface IValue<int> with
member _.Get() = 1
interface IValue<string> with
member _.Get() = "hello"
let o = BiValue()
let i = (o :> IValue<int>).Get() // 1
let s = (o :> IValue<string>).Get() // "hello"
Héritage
Défini avec mot clé inherit
type Base(x: int) =
do
printf "Base: "
for i in 1..x do printf "%d " i
printfn ""
type Child(y: int) =
inherit Base(y * 2)
do
printf "Child: "
for i in 1..y do printf "%d " i
printfn ""
let child = Child(1)
// Base: 1 2 3 4
// Child: 1
Last updated
Was this helpful?