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.
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}")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.
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"))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.
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())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.
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)3 accounts opened Grace
What you learned
- A
Classis a reference type;Newsets up each object, andSelfis 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 Fieldis set inNewand never changes after. Staticfields and Methods belong to the Class, and are used through its name.
The rules are in the language reference.
Report an issue with this page or with FutureBlitz on GitHub.