Skip to content
FutureBlitz

    Install

    The tour, 9 of 11

    Interfaces and generics

    Interfaces with default Methods, generic Functions and types, and constraints.

    An Interface is what a type promises to have. A Class Implements it, and code that takes the Interface takes an object of any of them. A Struct implements one too, for generic code, like a <T: Shape>, though only Classes’ objects are the Interface’s values.

    Import std.core
    
    Interface Shape
        Method Area(): Float
        Method Describe(): String => "a shape of area {Area()}"   // a default
    End Interface
    
    Class Circle Implements Shape
        Field r: Float
        New(r: Float)
            Self.r = r
        End New
        Method Area(): Float => 3.14159 * r * r
    End Class
    
    Class Square Implements Shape
        Field side: Float
        New(side: Float)
            Self.side = side
        End New
        Method Area(): Float => side * side
        Method Describe(): String => "a square of side {side}"
    End Class
    
    Local shapes: Shape[] = [Circle(1), Square(2)]
    For s In shapes
        Print(s.Describe())
    End For
    Output
    a shape of area 3.14159
    a square of side 2

    Generics

    A generic Function or type takes type parameters in angle brackets, and a constraint says what they must implement. std.core’s built-in Interfaces, like Comparable, Equatable, Hashable, Printable, and Numeric, are the usual ones.

    Import std.core
    
    Function Largest<T: Comparable>(items: T[]): T
        Local best = items[0]
        For item In items
            If item > best Then best = item
        End For
        Return best
    End Function
    
    Class Box<T>
        Field value: T
    
        New(value: T)
            Self.value = value
        End New
    
        Method Map<R>(f: Func(T): R): Box<R> => Box<R>(f(value))
    End Class
    
    Print(Largest([3, 9, 4]))
    Print(Largest(["pear", "apple", "plum"]))
    
    Local box = Box(21)
    Print(box.Map(Function(x: Int) => x * 2).value)
    Output
    9
    plum
    42

    The type arguments are worked out from the call when they can be, as Largest([3, 9, 4]) is a Largest<Int>. Next: concurrency.

    Next: Threads and coroutines

    Report an issue with this page or with FutureBlitz on GitHub.