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 equivalent? 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)
?
It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden. If you try to write a super class's constructor in the sub class compiler treats it as a method and expects a return type and generates a compile time error.
Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.
When a class inherits from a superclass, it inherits parts of the superclass methods and fields. The subclass can also override (redefine) the inherited methods. Fields cannot be overridden, but can be "shadowed" in subclasses.
Inheritance is necessary to override. 2. When we need to restrict only a child class to access its super class's data, at time, it is a good idea to make a class protected.
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?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With