I would like to use some case class features like the following:
val base: Base = new Derived
println(base.copy())
I cannot define both Base and Derived as case classes. And making any of them case class raises compiler error: Cannot resolve symbol copy.
So, there is a workaround with dispatching case class metods to children:
abstract class BaseWorkaround(name: String) {
def dispatchCopy: BaseWorkaround
}
case class DerivedWorkaround(name: String) extends BaseWorkaround(name) {
override def dispatchCopy: BaseWorkaround = copy()
}
val abbie: BaseWorkaround = DerivedWorkaround("Abbie")
println(abbie.dispatchCopy)
The workaround works, but looks cumbersome. Is there more elegant way to perform this behaviour?
You can refresh the information why inheritance of case classes is bad and what possible workarounds are:
Scala case class inheritance
Extend case class from another case class
Should I use the final modifier when declaring case classes?
case class inheriting another class/trait
What is *so* wrong with case class inheritance?
Inheriting properties among case class
Case classes are intended for algebraic data types in functional programming:
OOP and inheritance with them are weird. You should prefer composition over inheritance:
There are alternatives to case classes:
http://eed3si9n.com/contraband-an-alternative-to-case-class/
https://www.scala-sbt.org/contraband/
https://www.scala-sbt.org/1.x/docs/Datatype.html (sbt-datatype)
https://github.com/sbt/contraband
https://www.reddit.com/r/scala/comments/5xu085/contraband_an_alternative_to_case_class/
@datahttps://gitlab.com/fommil/attic/tree/master/stalagmite
@datahttps://github.com/alexarchambault/data-class
@data,@root/@branch/@leaf,@root/@branch/@asthttps://github.com/scalameta/scalameta/blob/v4.7.5/scalameta/common/shared/src/main/scala/org/scalameta/data/data.scala#L9-L21
https://github.com/scalameta/scalameta/blob/v4.7.5/scalameta/common/shared/src/main/scala/org/scalameta/adt/Adt.scala#L11-L19
https://github.com/scalameta/scalameta/blob/v4.7.5/scalameta/common/shared/src/main/scala/scala/meta/internal/trees/root.scala#L11
https://github.com/scalameta/scalameta/blob/v4.7.5/scalameta/common/shared/src/main/scala/scala/meta/internal/trees/branch.scala#L11
https://github.com/scalameta/scalameta/blob/v4.7.5/scalameta/common/shared/src/main/scala/scala/meta/internal/trees/ast.scala#L13
apply/unapply,copyetc. with macro-annotationsGenerate apply methods creating a class
how to efficiently/cleanly override a copy method
Prohibit generating of apply for case class
https://svejcar.dev/posts/2019/09/26/better-tostring-alternative-for-case-classes/
https://github.com/milessabin/shapeless/blob/main/examples/src/main/scala/shapeless/examples/alacarte.scala
https://github.com/milessabin/shapeless/blob/main/core/shared/src/test/scala/shapeless/alacarte.scala
Let's think what signature
copyinBaseshould have. My understanding is that you meantor
In principle,
def copyinDerived,def copyinBase,def name,def agein Base can be generated fromcase class Derived(name: String, age: Int). But what if there are several inheritors ofBase? Doesn'tBaseknow too much now aboutDerived?