Why shouldn't one use case classes exclusively ?
After all, they promote immutability, pattern matching over accessor methods etc ?
People frequently use case classes and then try to customize/abuse them to do something else than what case classes are supposed to do.
E.g. if you want to
you should use a normal class, even if you have to type a bit more.
Use a case class for pure, immutable and public data. Basically a tuple with named elements, nothing more. Use normal classes for e.g. handles to mutable resources (files, GUI controls etc.)
People frequently think that you can abuse case classes to do tasks reserved for normal classes. So here are a number of examples of misuse of case classes:
Members of a case class are never really private
case class Foo(x: Int, private val y: String)
val x = Foo(1, "Secret")
x.y // does not work, because y is private
x.productElement(1) // still does work
Foo.unapply(Foo(1,2)).get._2 // another, more typesafe way to get at the private fields
You might think that by making the constructor private, it is possible to enforce invariants. In the example below, you might think that it is impossible to create a range with min > max.
case class Range private (min: Int, max: Int)
object Range {
def create(a: Int, b: Int): Range =
if(a < b) new Range(a, b) else new Range(b, a)
}
But that is not the case:
scala> val wrong = Range.create(2,1).copy(min = 1000)
wrong: Range = Range(1000,2)
You would have to override the copy method as well. By the time you have made this really watertight, you might as well have used a normal class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With