// Interfaces
type IShape =
abstract Area: float
abstract Name: string
abstract Scale: float -> IShape
type Circle(r: float) =
interface IShape with
member _.Area = System.Math.PI * r * r
member _.Name = "circle"
member _.Scale k = Circle(r * k) :> IShape
let shape = Circle 2.0 :> IShape // upcast (interfaces are explicit in F#)
shape.Area
// Abstract classes and inheritance
[<AbstractClass>]
type Animal(name: string) =
member _.Name = name
abstract Speak: unit -> string
default this.Describe() = $"{name} says {this.Speak()}" // virtual method with default
abstract Describe: unit -> string
type Dog(name) =
inherit Animal(name)
override _.Speak() = "Woof"
type Puppy(name) =
inherit Dog(name)
override this.Describe() = base.Describe() + " (squeaky)"
let animals: Animal list = [ Dog "Rex"; Puppy "Bit" ]
animals |> List.iter (fun a -> printfn "%s" (a.Describe()))
// Casting
let d = Dog "Rex"
let a = d :> Animal // upcast
let back = a :?> Dog // downcast (may throw InvalidCastException)
match a with :? Dog as dog -> dog.Speak() | _
…