Reputation: 4992
Let us assume we have the two following classes:
abstract case class MyParent(param: Int) {
// ...
}
case class MyChild(param: Int) extends MyParent(param: Int) {
// ... ^^^^^ ^^^^^
}
Making them both case classes resulted in an error in both param
usage places, which says that it needs the override
modifier that will override the value from the parent class. This looks strange to me.. why do I have to invent other param names here.. why is this order of things enforced? Where is the profit?
Upvotes: 1
Views: 880
Reputation: 53705
As far as my limited Scala knowledge goes, case classes are typically used for immutable algebraic data types and pattern matching. Therefore, instead of creating a "child class", you should probably instead create a class which contains the "parent" class.
> case class MyParent(param: Int)
defined class MyParent
> case class MyChild(param: Int, parent: MyParent)
defined class MyChild
> def foo(c: MyChild) = c match {
case MyChild(p, MyParent(p2)) => println("p: " + p + ", p2 " + p2)
}
foo: (c: MyChild)Unit
> foo(MyChild(3, MyParent(4)))
p: 3, p2 4
Upvotes: 1
Reputation: 170815
Where is the profit?
Simply the lack of a not-too-useful special case. param
in case class MyChild(param: Int)
is a class member as well as a constructor parameter, so one of ancestors already has a (non-abstract) param
member, it has to be overridden. And Scala requires override
keyword when overriding everywhere else, so it requires it here as well.
Upvotes: 1
Reputation: 3722
You never should derive a case class from another case class!
Try this in a REPL started with scala -deprecation:
scala> case class Foo(foo: String)
defined class Foo
scala> case class Bar(override val foo: String) extends Foo(foo)
<console>:9: warning: case class `class Bar' has case ancestor `class Foo'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.
Upvotes: 7
Reputation: 4345
A quick fix for that is to do this
abstract case class MyParent(param: Int) {
println("Form parent : " + param)
}
case class MyChild(override val param: Int) extends MyParent(param) {
println("Form child : " + param)
}
val c = MyChild(10);
This will result in this
>> From parent : 10
>> From child : 10
Actually the extends MyParent()
is not like in Java. This is a way to tell MyChild
extends MyParent
, and call the super constructor of the latter at first.
Upvotes: 1