Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting properties among case class

What's the best way to inherit some properties from a case class?

Let's say there's a case class with some properties

case class aggregations (aggregation1: Int, aggregation2: Int)

Two other case classes (case class A & case class B) will have the above parameters plus some extra fields. I'm trying to avoid code duplication and wondering what's the best strategy.

Found a thread discussing the same Scala case class inheritance but not sure whether composition/inheritance is the most suitable option here.

like image 525
Nithin Chandy Avatar asked Jan 31 '26 21:01

Nithin Chandy


1 Answers

1) I tend to define trait when properties are shared in scala, though I would define interface and then abstract class in java.

parent class with shared members m1, m2

scala> trait Parent { def m1: Int, def m2: Int}

child classes with their own members

scala> case class Child1(val m1: Int, val m2: Int, val m3: Int) extends Parent
defined class Child1

scala> case class Child2(val m1: Int, val m2: Int, val m4: String) extends Parent
defined class Child2

using child classes

scala> Child1(1, 2, 3) == Child1(1, 2, 3)
res2: Boolean = true

scala> Child2(1, 2, "urayagppd") == Child2(1, 2, "prayagupd")
res4: Boolean = false

Also described in the post you mentioned.

NOTE : case-to-case inheritance is prohibited in scala.

scala> case class A(m1: Int)
defined class A

scala> case class B(m1: Int, m2: Int) extends A(m1)
<console>:13: error: case class B has case ancestor A, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
       case class B(m1: Int, m2: Int) extends A(m1)

2) If you don't like explicit overriding parent properties in child classes, use composition.

parent class

scala> trait Parent
defined trait Parent

scala> case class ParentClass(val m1: Int, val m2: Int) extends Parent
defined class ParentClass

Child classes

scala> case class Child1(parent: ParentClass, val newMember: Int) extends Parent
defined class Child1

scala> Child1(ParentClass(100, 200), 400)
res0: Child1 = Child1(ParentClass(100,200),400)

scala> case class Child2(parent: ParentClass, val newMember2: String) extends Parent
defined class Child2

scala> Child2(ParentClass(100, 200), "inheritence sucks")
res2: Child2 = Child2(ParentClass(100,200),inheritence sucks)
like image 140
prayagupa Avatar answered Feb 03 '26 10:02

prayagupa