This is not true. And it's worse than a lie.
As mentioned by aepurniet in any case, the successor of the class that narrows the scope should override this equality, since pattern matching should work just like equality (if you try to match Point as ColoredPoint , then it will not match, since color does not exist )
This provides an understanding of how you can implement case class hierarchy equality.
case class Point(x: Int, y: Int) case class ColoredPoint(x: Int, y: Int, c: Color) extends Point(x, y) Point(0, 0) equals ColoredPoint(0, 0, RED) // false Point(0, 0) equals ColoredPoint(0, 0, null) // true ColoredPoint(0, 0, RED) equals Point(0, 0) // false ColoredPoint(0, 0, null) equals Point(0, 0) // true
Ultimately, it is possible to satisfy the equality equality requirements even for the successor of the case class (without overriding equality).
case class ColoredPoint(x: Int, y: Int, c: String) class RedPoint(x: Int, y: Int) extends ColoredPoint(x, y, "red") class GreenPoint(x: Int, y: Int) extends ColoredPoint(x, y, "green") val colored = ColoredPoint(0, 0, "red") val red1 = new RedPoint(0, 0) val red2 = new RedPoint(0, 0) val green = new GreenPoint(0, 0) red1 equals colored // true red2 equals colored // true red1 equals red2 // true colored equals green // false red1 equals green // false red2 equals green // false def foo(p: GreenPoint) = ???