One feature provided for free by case classes is an auto-generated equals
method that checks the value equality of all individual member fields instead of just checking the reference equality of the objects.
With ordinary classes:
class Foo(val i: Int)
val a = new Foo(3)
val b = new Foo(3)
println(a == b)// "false" because they are different objects
With case classes:
case class Foo(i: Int)
val a = Foo(3)
val b = Foo(3)
println(a == b)// "true" because their members have the same value