How to use a case classes when hierarchy is needed?

case-class, scala

Solution

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.

sealed trait Parent {
  /* implement all common properties */
}

case class A extends Parent

case class B extends Parent {
  /*add all stuff you want*/
}

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"

Problem

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?

Original source