Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is *so* wrong with case class inheritance?

While looking for something else, quite out of mere coincidence I stumbled upon few comments about how diabolical case class inheritance is. There was this thing called ProductN , wretches and kings, elves and wizards and how some kind of a very desirable property is lost with case classes inheritance. So what is so wrong with case class inheritance ?

like image 682
Ashkan Kh. Nazary Avatar asked Jun 22 '12 15:06

Ashkan Kh. Nazary


People also ask

Can case class be extended?

The answer is simple: Case Class can extend another Class, trait or Abstract Class. Create an abstract class which encapsulates the common behavior used by all the classes inheriting the abstract class.

What is a case class?

A case class has all of the functionality of a regular class, and more. When the compiler sees the case keyword in front of a class , it generates code for you, with the following benefits: Case class constructor parameters are public val fields by default, so accessor methods are generated for each parameter.

What is the difference between class and case class in Scala?

A class can extend another class, whereas a case class can not extend another case class (because it would not be possible to correctly implement their equality).

What is inheritance in Scala?

Inheritance is an important pillar of OOP(Object Oriented Programming). It is the mechanism in Scala by which one class is allowed to inherit the features(fields and methods) of another class.


1 Answers

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):

  1. For all x; x equals x is true (reflexive)
  2. For x, y, z; if x equals y and y equals z then x equals z (transitive)
  3. 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.

like image 147
oxbow_lakes Avatar answered Sep 28 '22 04:09

oxbow_lakes