I know that you’re not allowed to inherit from case classes but how would you do when you really need to? We have two classes in a hierarchy, both contain many fields, and we need to be able to create instances of both. Here’s my options:
- If I’d make the super class a usual class instead of a case class – I’d lose all the case class goodness such as toString, equals, hashCode methods etc.
- If I keep it as a case class, I’d break the rule of not inheriting from case classes.
- If I use composition in the child class – I’d have to write lots of methods and redirect them to the other class – which would mean lots of work and would feel non-Scalaish.
What should I do? Isn’t it quite a common problem?
Yes this is quite a recurrent problem, what I would suggest is to create a trait with all parent properties, create a case class which just implements it and then another one which inherits of it with more properties.
A good way of seeing it is a tree, traits are nodes and case classes are leaves.
You can use a trait or an abstract class depending on your needs for the parent. However, avoid using a class because you would be able to create instances of it, which would not be elegant.
EDIT: As suggested in comments, you can seal the trait in order to have exceptions at compilation if not all case classes are covered in a pattern matching. It is for example explained in chapter 15.5 of “Programming in Scala”