Classes & Objects

Parameters without val/var are private constructor parameters (visible inside the class only).

11.1 Classes

Parameters without val/var are private constructor parameters (visible inside the class only).

class Person(val name: String, var age: Int):      // primary constructor; val/var make fields
  require(age >= 0, "age must be non-negative")     // constructor validation

  private var nicknames: List[String] = Nil

  def greet(): String = s"Hi, I'm $name"
  def birthday(): Unit = age += 1
  def addNickname(n: String): Unit = nicknames ::= n

  override def toString: String = s"Person($name, $age)"

val p = Person("Ann", 30)        // `new` is optional in Scala 3 (creator applications)
p.name                           // "Ann"
p.age = 31
p.birthday()

11.2 Auxiliary constructors

class Point(val x: Double, val y: Double):
  def this() = this(0, 0)
  def this(xy: Double) = this(xy, xy)

11.3 Singleton objects

Objects are lazily initialized singletons — Scala's replacement for static.

object MathUtils:
  val Pi = 3.14159
  def square(x: Double): Double = x * x

MathUtils.square(3)

11.4 Companion objects

A class and object with the same name in the same file can access each other's private members:

class Circle private (val radius: Double):
  def area: Double = Circle.calcArea(radius)

object Circle:
  private def calcArea(r: Double) = math.Pi * r * r
  def apply(radius: Double): Circle =                 // factory
    require(radius > 0)
    new Circle(radius)
  def unit: Circle = new Circle(1)

val c = Circle(2.0)

11.5 Inheritance

override is mandatory when overriding concrete members.

sealed restricts subclasses to the same file (enables exhaustive matching).

open (Scala 3) marks classes intended for extension in other files.

abstract class Animal(val name: String):
  def sound: String                       // abstract member
  def speak(): String = s"$name says $sound"

class Dog(name: String) extends Animal(name):
  def sound = "Woof"
  override def speak(): String = super.speak() + "!"

final class Cat(name: String) extends Animal(name):    // final: cannot be extended
  val sound = "Meow"

11.6 Abstract members & type members

abstract class Buffer:
  type Elem
  val capacity: Int
  def add(e: Elem): Unit

11.7 Equality & hashing

Override equals and hashCode together (or just use case classes). Use canEqual in open hierarchies; Scala 3 offers multiversal equality (CanEqual, -language:strictEquality) to forbid comparing unrelated types.

11.8 Value classes (Scala 2 style)

In Scala 3, prefer opaque types (§28).

class Meters(val value: Double) extends AnyVal:
  def +(o: Meters) = Meters(value + o.value)