Interfaces
Interfaces are declared in a similar fashion to classes but with only abstract members, for example
type ICalculator = abstract member Add : int -> int -> int
Classes
type Calculator() = member this.Add a b = a + b
Here we declared a constructor with no arguments, but we could also declare a constructor which takes arguments, such as
type Calculator(a, b) = member this.Add = a + b
We can also declare the constructors in the following manner
type Calculator1 = new () = {} member this.Add = a + b type Calculator2 = new (a, b) = { (* do something with the values *) } member this.Add = a + b
Leading on from this way of declaring constructors, we can also declare multiple constructors in the following manner
type SomeClass = val data : string new () = { data = "undefined"} new (d) = { data = d }
Here we’ve declared a default constructor and one which takes a single argument.
or implementing the previously declared ICalculator we have
type Calculator() = interface ICalculator with member this.Add a b = a + b
To access the Add method we need to cast our value to the specific interfaces, for example
let calc = new Calculator() (calc :> ICalculator).Add 2 3
The :> is the cast operator.
We can also implement an interface in an anonymous class, for example
let calculator() = { new ICalculator with member this.Add a b = a + b }
Inheritance
type Calculator() = member this.Add a b = a + b type NewCalculator() = inherit Calculator()
Virtual functions
To declare a function as virtual we need to both declare it as abstract and create a default implementation, for example
type MyClass() = abstract member myfunction : unit -> unit default u.myfunction() = printfn "hello"
Note: the “u.” part of the above is a self identifier. Unlike C# which has the implicit “this” identifier, we can define whatever name we wish for the self identifier
We can define a self identifier at the class level using
type MyClass() as myself = abstract member myfunction : unit -> unit default myself.myfunction() = printfn "hello"