Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending scala case class without constantly duplicating constructors vals?

Is there a way to extend a case class without constantly picking up new vals along the way?

For example this doesn't work:

case class Edge(a: Strl, b: Strl) case class EdgeQA(a: Strl, b: Strl, right: Int, asked: Int) extends Edge(a, b) 

"a" conflicts with "a", so I'm forced to rename to a1. But I don't want all kinds of extra public copies of "a" so I made it private.

case class Edge(a: Strl, b: Strl) case class EdgeQA(private val a1: Strl, private val b1: Strl, right: Int, asked: Int) extends Edge(a, b) 

This just doesn't seem clean to me... Am I missing something?

like image 644
LaloInDublin Avatar asked Jun 22 '12 23:06

LaloInDublin


People also ask

Can you extend a case class in Scala?

Case classes can't be extended via subclassing. Or rather, the sub-class of a case class cannot be a case class itself.

How do I extend a class in Scala?

To extend a class in Scala we use extends keyword. there are two restrictions to extend a class in Scala : To override method in scala override keyword is required. Only the primary constructor can pass parameters to the base constructor.

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


2 Answers

As the previous commenter mentioned: case class extension should be avoided but you could convert your Edge class into a trait.

If you want to avoid the private statements you can also mark the variables as override

trait Edge{   def a:Strl   def b:Strl }  case class EdgeQA(override val a:Strl, override val b:Strl, right:Int, asked:Int ) extends Edge 

Don't forget to prefer def over val in traits

like image 187
bajohns Avatar answered Sep 18 '22 06:09

bajohns


This solution offers some advantages over the previous solutions:

trait BaseEdge {   def a: Strl   def b: Strl } case class Edge(a:Strl, b:Strl) extends BaseEdge case class EdgeQA(a:Strl, b:Strl, right:Int, asked:Int ) extends BaseEdge 

In this way:

  • you don't have redundant vals, and
  • you have 2 case classes.
like image 44
david.perez Avatar answered Sep 20 '22 06:09

david.perez