One word: equality
case
classes come with a supplied implementation of equals
and hashCode
. The equivalence relation, known as equals
works like this (i.e. must have the following properties):
- For all
x
; x equals x
is true
(reflexive)
- For
x
, y
, z
; if x equals y
and y equals z
then x equals z
(transitive)
- For
x
, y
; if x equals y
then y equals x
(symmetric)
As soon as you allow for equality within an inheritance hierarchy you can break 2 and 3. this is trivially demonstrated by the following example:
case class Point(x: Int, y: Int)
case class ColoredPoint(x: Int, y: Int, c: Color) extends Point(x, y)
Then we have:
Point(0, 0) equals ColoredPoint(0, 0, RED)
But not
ColoredPoint(0, 0, RED) equals Point(0, 0)
You might argue that all class hierarchies may have this problem, and this is true. But case classes exist specifically to simplify equality from a developer's perspective (among other reasons), so having them behave non-intuitively would be the definition of an own goal!
There were other reasons as well; notably the fact that copy
did not work as expected and interaction with the pattern matcher.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…