Case Classes (Scala 3 Video)
Introduction
A Scala case
class is like a regular class, with additional functionality built in:
- Has an
apply
method that works like a factory method - Constructor parameters are public
val
fields - An
unapply
method makes them easy to use inmatch
expressions - A
copy
method lets you “update while you copy” equals
andhashCode
methods are generated- Lets you compare (
==
) values, and use in Maps and Sets (sorted), sorting in general
- Lets you compare (
- A default
toString
method is generated - Similar to:
data class
in Kotlin- Record in Java 14+
- Struct in C
Case class examples
Some case
class examples:
// CREATE
case class Person(firstName: String, lastName: String)
// this uses the APPLY method that is generated for you:
val a = Person("Reginald", "Dwight")
// constructor parameters are VAL fields
a.firstName // "Reginald"
a.firstName = "Elton" // error: Reassignment to val firstName
case
classes with match
expressions:
// step 1: show that these DO NOT work with match
class Dog(val name: String) extends Animal
class Cat(val name: String) extends Animal
// error without `case`: "Dog cannot be used as an extractor
// in a pattern because it lacks an unapply or unapplySeq method"
// step 2: show that these DO work with match
trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
def speak(a: Animal): String = a match
case Dog(name) => s"Dog ‘$name’ says woof"
case Cat(name) => s"Cat ‘$name’ says meow"
// usage:
val d = Dog("Rover")
val c = Cat("Morris")
speak(d)
speak(c)
Update as you copy:
val a = Person("Reginald", "Dwight")
a.firstName // "Reginald"
a.lastName // "Dwight"
// COPY
val b = a.copy(
firstName = "Elton",
lastName = "John"
)
b.firstName // "Elton"
b.lastName // "John"
equals
and hashCode
, Part 1:
val s = scala.collection.SortedSet(10, 4, 8, 2)
class Human(val name: String) // doesn’t work (plain class)
val a = Human("Alvin")
val b = Human("Alvin")
a == b // false
case class Human(name: String) // works!
val a = Human("Alvin")
val b = Human("Alvin")
a == b // true
equals
and hashCode
, Part 2:
// FAILS: the resulting Set contains 3 Alvins (plain class)
class Human(val name: String):
override def toString = name
val s = Set(
Human("Alvin"),
Human("Alvin"),
Human("Alvin"),
)
// WORKS: the resulting Set contains 1 Alvin
case class Human(name: String)
val s = Set(
Human("Alvin"),
Human("Alvin"),
Human("Alvin"),
Human("Fred"),
Human("Bert"),
)
Example case class constructors
case class Address(
street1: String,
street2: Option[String],
city: String,
state: String,
zipCode: String
)
case class Customer(
name: String,
phone: String,
address: Address
)
case class Order(
pizzas: Seq[Pizza],
customer: Customer
)
enum BookFormat:
case Paperback, Hardcover, Kindle, EPub
case class Book(
title: String,
author: String,
isbn: String,
publisher: Publisher,
datePublished: Date,
numPages: Int,
formatsAvailable: Seq[BookFormat]
)
More reading
Update: All of my new videos are now on
LearnScala.dev