Skip to content
FutureBlitz

    Install

    Your own types, 2 of 8

    Classes

    Make reference types with constructors, Methods, ReadOnly fields, and Statics, and see objects shared.

    What you’ll build

    A bank Account that has an owner, takes deposits and withdrawals, and counts how many accounts have been opened. A Class suits it: an account is one thing with an identity, which every part of the program that has it should see the same way.

    A Class and its constructor

    A Class declares fields and Methods as a Struct does. Its constructor is New, which sets the fields up. Calling the Class’s name makes an object and runs its New. A field without a default starts at its type’s zero, and one that has no zero, like another Class, must be set in New.

    bank.fb
    Import std.core
    
    Class Account
        Field owner: String
        Field balance: Int
    
        New(owner: String, deposit: Int = 0)
            Self.owner = owner
            balance = deposit
        End New
    
        Method Deposit(amount: Int)
            balance += amount
        End Method
    
        Method Withdraw(amount: Int): Bool
            If amount > balance Then Return False
            balance -= amount
            Return True
        End Method
    End Class
    
    Local account = Account("Ada", 100)
    account.Deposit(50)
    Print(account.Withdraw(500), account.Withdraw(20))
    Print("{account.owner} has {account.balance}")
    Output
    False True
    Ada has 130

    Self is the object a Method or New runs on. Self.owner is the field, where the parameter of the same name would hide it. A Class’s Methods can always change its fields, so a Class has no ByRef Method.

    Objects are shared

    A variable of a Class type holds a reference to an object. Assigning it to another variable, or passing it to a function, shares the same object, so a change through one reference shows through all of them.

    bank.fb
    Import std.core
    
    Class Account
        Field owner: String
        Field balance: Int
    
        New(owner: String)
            Self.owner = owner
        End New
    End Class
    
    Function PayInterest(account: Account)
        account.balance += account.balance / 10
    End Function
    
    Local mine = Account("Ada")
    Local alsoMine = mine
    alsoMine.balance = 200
    PayInterest(mine)
    Print(mine.balance, alsoMine.balance)
    Print(mine == alsoMine, mine == Account("Ada"))
    Output
    220 220
    True False

    == on objects asks whether they’re the same object, unless the Class gives an == of its own. Compare this with Structs, whose copies are separate.

    ReadOnly fields and visibility

    A ReadOnly Field can be set only in its Class’s New, so it never changes after the object is made. Public lets code in other files use a type or a member; without it, each is private to its file. A member is seen no further than its type, so a Public member needs a Public Class. Visibility matters once a program has several files.

    bank.fb
    Import std.core
    
    Public Class Account
        Public ReadOnly Field Owner: String
        Field balance: Int
    
        Public New(owner: String)
            Owner = owner
        End New
    
        Public Method Balance(): Int => balance
    End Class
    
    Local account = Account("Grace")
    Print(account.Owner, account.Balance())
    Output
    Grace 0

    Writing account.Owner = "Alan" is an error, since Owner is ReadOnly.

    Statics

    A Static Field is one variable for the whole Class, not one per object, and a Static Method runs without an object. Both are used through the Class’s name.

    bank.fb
    Import std.core
    
    Class Account
        ReadOnly Field Owner: String
        Static Field opened: Int
    
        New(owner: String)
            Owner = owner
            opened++
        End New
    
        Static Method Opened(): Int => opened
    End Class
    
    Local accounts = [Account("Ada"), Account("Alan"), Account("Grace")]
    Print("{Account.Opened()} accounts opened")
    Print(accounts[2].Owner)
    Output
    3 accounts opened
    Grace

    What you learned

    • A Class is a reference type; New sets up each object, and Self is the object.
    • Assigning or passing an object shares it, so changes show through every reference.
    • == on objects compares identity unless the Class defines its own.
    • A ReadOnly Field is set in New and never changes after.
    • Static fields and Methods belong to the Class, and are used through its name.

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