Classes and objects organise state and behaviour in every Scala codebase.
A class declares its primary constructor in the header: class Account(val owner: String, private var balance: Double). A val parameter becomes a public read-only field, var a mutable one, and a plain parameter is private to the class. The class body runs as part of the constructor, so require(balance >= 0) there validates input. In Scala 3 new is optional: Account("ana", 10) works.
Members are public by default; private and protected restrict them, and private[pkg] opens access to a package. Auxiliary constructors (def this(...)) exist but default parameters usually make them unnecessary.
An object is a singleton: one instance, created lazily on first use. Use it for utilities, constants and entry points.
An object with the same name as a class in the same file is its companion. They can access each other's private members, and the companion is the conventional home for factory methods (apply) and constants. Account.empty("bo") reads better than a constructor, and a private constructor plus a companion apply lets you validate or cache instances.
Methods that take one argument can be written infix (a max b), and symbolic names are allowed (def +(other: Money)), though libraries use them sparingly. override def toString customises printing.
Example
class Account(val owner: String, private var balance: Double):
require(balance >= 0, "negative balance")
def deposit(amount: Double): Unit = balance += amount
def current: Double = balance
override def toString = s"Account($owner, $balance)"
object Account:
private var created = 0
def empty(owner: String): Account =
created += 1
Account(owner, 0)
def count: Int = created
object MathUtil:
val Tau = 2 * math.Pi
def clamp(x: Int, lo: Int, hi: Int) = x max lo min hi
@main def demo(): Unit =
val a = Account.empty("ana")
a.deposit(25)
println(a) // Account(ana, 25.0)
println(a.current) // 25.0
println(Account.count) // 1
println(MathUtil.clamp(15, 0, 10)) // 10
// a.balance // error: balance is privateRemember
- Constructor parameters with
val/varbecome fields - An
objectis a lazily created singleton - A companion object shares privates with its class and holds factories
newis optional in Scala 3
Watch out for
- Leaving a field as a plain constructor parameter and then trying to read it from outside the class.