You want to control the superclass constructor that’s called when you create constructors in a subclass.
This is a bit of a trick question, because you can control the superclass constructor that’s called by the primary constructor in a subclass, but you can’t control the superclass constructor that’s called by an auxiliary constructor in the subclass.
When you define a subclass in Scala, you control the superclass
constructor that’s called by its primary constructor when you define the
extends
portion of the subclass
declaration. For instance, in the following code, the Dog
class is defined to call the primary
constructor of the Animal
class,
which is a one-arg constructor that takes name
as its parameter:
class
Animal
(
var
name
:
String
)
{
// ...
}
class
Dog
(
name
:
String
)
extends
Animal
(
name
)
{
// ...
}
However, if the Animal
class
has multiple constructors, the primary constructor of the Dog
class can call any of those
constructors.
For example, the primary constructor of the Dog
class in the following code calls the
one-arg auxiliary constructor of the Animal
class by specifying that constructor in
its extends
clause:
// (1) primary constructor
class
Animal
(
var
name
:
String
,
var
age
:
Int
)
{
// (2) auxiliary constructor
def
this
(
name
:
String
)
{
this
(
name
,
0
)
}
override
def
toString
=
s
"$name is $age years old"
}
// calls the Animal one-arg constructor
class
Dog
(
name
:
String
)
extends
Animal
(
name
)
{
println
(
"Dog constructor called"
)
}
Alternatively, it could call the two-arg primary constructor of
the Animal
class:
// call the two-arg constructor
class
Dog
(
name
:
String
)
extends
Animal
(
name
,
0
)
{
println
(
"Dog constructor called"
)
}
Regarding auxiliary constructors, because the first line of an auxiliary constructor must be a call to another constructor of the current class, there is no way for auxiliary constructors to call a superclass constructor.
As you can see in the following code, the primary constructor of
the Employee
class can call any
constructor in the Person
class,
but the auxiliary constructors of the Employee
class must call a
previously defined constructor of its own class with the this
method as its first line:
case
class
Address
(
city
:
String
,
state
:
String
)
case
class
Role
(
role
:
String
)
class
Person
(
var
name
:
String
,
var
address
:
Address
)
{
// no way for Employee auxiliary constructors to call this constructor
def
this
(
name
:
String
)
{
this
(
name
,
null
)
address
=
null
}
override
def
toString
=
if
(
address
==
null
)
name
else
s
"$name @ $address"
}
class
Employee
(
name
:
String
,
role
:
Role
,
address
:
Address
)
extends
Person
(
name
,
address
)
{
def
this
(
name
:
String
)
{
this
(
name
,
null
,
null
)
}
def
this
(
name
:
String
,
role
:
Role
)
{
this
(
name
,
role
,
null
)
}
def
this
(
name
:
String
,
address
:
Address
)
{
this
(
name
,
null
,
address
)
}
}
Therefore, there’s no direct way to control which superclass constructor is called from an auxiliary constructor in a subclass. In fact, because each auxiliary constructor must call a previously defined constructor in the same class, all auxiliary constructors will eventually call the same superclass constructor that’s called from the subclass’s primary constructor.
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.