Interface name begins with I to follow .NET convention
Arguments can be named (without parentheses otherwise š„)
[<Interface>]
type IPrintable =
abstract member Print : format: string -> unit
You can also use verbose syntax with an interface ... end block.
ā Not idiomatic except in the case of a member-less interface a.k.a marker interface.
type IMarker = interface end
Implementation
2 ways of implementing an interface:
In an object expression š
In a type (as in CāÆ)
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}]"
Keyword
This interface F⯠keyword matches the implements keyword in Java and TypeScript.
Default implementation
F⯠5.0 supports interfaces defining methods with default implementations written in C⯠8+ but does not allow them to be defined directly in FāÆ.
Keyword
Don't confuse with default keyword: it's supported only in classes!
F⯠interface is explicit
F⯠interface implementation
ā” Explicit implementation of an interface in CāÆ
ā Interface methods are accessible only by upcasting:
[<Interface>]
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() // upcast operator
// [1..5]
Implementing a generic interface
[<Interface>]
type IValue<'T> =
abstract member Get : unit -> 'T
// Contrived example for demo purpose
type DoubleValue(i, s) =
interface IValue<int> with
member _.Get() = i
interface IValue<string> with
member _.Get() = s
let o = DoubleValue(1, "hello")
let i = (o :> IValue<int>).Get() // 1
let s = (o :> IValue<string>).Get() // "hello"
Inheritance
Defined with inherit keyword
type A(x: int) =
do
printf "Base (A): "
for i in 1..x do printf "%d " i
printfn ""
type B(y: int) =
inherit Base(y * 2) // š
do
printf "Child (B): "
for i in 1..y do printf "%d " i
printfn ""
let child = B(1)
// Base: 1 2
// Child: 1
// val child: B