Start learning free

LESSON 153 OF 348 · SCALA ESSENTIALS

Case Classes in Scala in Scala

Lesson

Most of the classes you will ever write do one humble job: hold data. A User is a name and an age; a Point is an x and a y. In Scala you can declare such a class in a single line — the fields live right in the parentheses, no body needed:

class Visitor(val name: String, val age: Int)

But a plain class only stores the data — it doesn't know how to show it or compare it. Every class inherits two defaults: toString prints the class name plus a memory address, and == asks "are these the very same object?" — not "do they hold the same values?".


The trap:

Sooner or later, every Scala beginner prints an object, or compares two objects built from identical values — and gets this:

val a = new Visitor("Ana", 25)
val b = new Visitor("Ana", 25)
println(a)       // expecting the data...
println(a == b)  // expecting true...
Visitor@1b6d3586
false

No name, no age — just Visitor@ and a hex address. And two visitors with the exact same data are "not equal", because the default equals compares identity (the address), not contents.


The fix — one keyword:

Mark the class with case and the compiler generates the useful versions for you, straight from the constructor parameters (which automatically become public val fields — no val keyword needed):

case class User(name: String, age: Int)

println(User("Ana", 25))                    // User(Ana,25) — no `new` needed
println(User("Ana", 25) == User("Ana", 25)) // true — compares values

You also get copy for free: it clones an object while changing only the fields you name — ana.copy(name = "Bob") keeps the age and swaps the name. Since the fields are immutable vals, this is the idiomatic way to get a "changed" version without touching the original.

And copy really is a case-class exclusive — call it on a plain class and the compiler stops you:

-- [E008] Not Found Error: p1.scala:9:14 ---------------------------------------
9 |val other = a.copy(name = "Bob")
  |            ^^^^^^
  |            value copy is not a member of Visitor

Assignment
Follow the Coding Tutorial to see the freebies in action — and the plain-class trap right next to them:

  • Declare case class User with name: String and age: Int.
  • Create ana = User("Ana", 25) and print her — the generated toString does the formatting.
  • Create twin from the same values and print whether ana == twin.
  • Declare a regular class Visitor(val name: String, val age: Int), build v1 and v2 from identical values with new, and print whether v1 == v2.
  • Make bob with ana.copy(name = "Bob") and print him.

The exact expected output is:

ana = User(Ana,25)
same = true
plain same = false
bob = User(Bob,25)

Hint
If your output looks like User@1b6d3586, you forgot the case keyword. To embed a comparison in a printed string, wrap it in braces: s"same = ${ana == twin}".


STEP 1 OF 11
    Ctrl + Enter to check

    Case Classes in Scala

    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free