Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 397
soc Avatar asked Jul 11 '11 22:07

soc


People also ask

What happens when we override a constructor?

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.

Why constructors are not inherited and override?

Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

Does inheritance removes any fields or methods of super class?

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.

Is overriding necessary for inheritance?

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.


1 Answers

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

like image 195
Aaron Novstrup Avatar answered Sep 27 '22 16:09

Aaron Novstrup