Differences when overriding inherited constructor fields?
Consider this simple Scala class:
class A(val d: Int)
Is there a difference in Scala (either in behaviour or generated bytecode) between
class B(d: Int) extends A(d)
and
class B(override val d: Int) extends A(d)
or are both eq开发者_StackOverflow中文版uivalent? If they are different, what would be the specific usecase for each of them?
Would it be different if A
was defined as class A(var d: Int)
?
For vals, there is no semantic difference. However, there may be a difference in the generated bytecode. In particular, if a method defined in the derived class refers to d
, it refers to the constructor parameter d
rather than to the val
of the same name. This is implemented via an additional private field generated for the derived class.
For vars, there is a difference in behavior. Without an override, any methods that refer to d
from within the derived class will be referring to the constructor parameter, while callers referencing d
from outside the class will get the field. In this case, the two values may differ (if the value has changed since construction).
Here's a session that demonstrates the behavior with a var:
scala> class A(var d: Int)
defined class A
scala> class B(d: Int) extends A(d) { override def toString = "d: " + d }
defined class B
scala> val b = new B(1)
b: B = d: 1
scala> b.d = 2
scala> b.d
res1: Int = 2
scala> b
res2: B = d: 1
This question is related: Idiomatic Scala way to deal with base vs derived class field names?.
精彩评论