Before reading this post, please read my previous post about “Scala Primary Constructor In-Depth”.
Post Brief TOC
- Introduction
- What is an Auxiliary Constructor?
- Auxiliary Constructor Advantages and Disadvantages
- Scala Auxiliary Constructor Examples
- Scala Auxiliary Constructor Rules
- Constructor Overloading With Auxiliary constructors
Introduction
A Scala class can contain two kinds of constructors:
- Primary Constructor
- Auxiliary Constructor
We have already discussed about Primary Constructor in my previous post. In this post, we are going to discuss about Auxiliary Constructors in-depth with suitable examples.
What is an Auxiliary Constructor?
In Scala, We can define Auxiliary Constructors like methods by using “def” and “this” keywords. “this” is the constructor name.
Auxiliary Constructor is also know as Secondary Constructor. A Scala class can contain zero or one or more Auxiliary Constructors.
Auxiliary Constructor Advantage and Disadvantage
What is the main Advantage of Auxiliary Constructors in Scala?
In Scala, Auxiliary Constructors are used to provide Constructors Overloading.
What is the main Disadvantage of Auxiliary Constructors in Scala?
We need to write lot of code to provide Constructors Overloading using Auxiliary Constructors. Then how to solve this problem? Please go through last section in this post.
We should use same “this” as Auxiliary Constructor name, then how do we define more Auxiliary Constructors in Scala. We can define multiple Auxiliary Constructors by using different parameters list.
What is Different Parameters list to a Constructor or Method or Function?
Different parameters list means:
a) Different in number of parameters or
b) Different in Parameter type
Now we will discuss Auxiliary Constructors with syntax and examples in next section.
Scala Auxiliary Constructor Examples:-
We define Auxiliary Constructors in Class Body with “def” and “this” keywords, but not in Class Definition. We use Class Definition to declare Primary Constructor.
Important Point to Remember:-
NOTE:-Each Auxiliary Constructor should call one of the previous defined constructor. An Auxiliary Constructor can call either Primary Constructor or another Auxiliary constructors by using “this” name.
Example-1:-
Create a Scala class with one Primary Constructor and Zero-Argument Auxiliary Constructor.
Employee1.scala
1 2 3 4 5 6 7 8 9 |
class Employee1(val empId : Int, val empName:String){ println("From Primary Constructor") def this(){ this(0,null) println("From Zero-Argument Auxiliary Constructor") } } |
Test Employee1.scala:-
To test the about program, we are going to write some sample examples as shown below:
Employee1Test1.scala
1 2 3 4 5 |
object Employee1Test1 extends App{ val emp1 = new Employee1() } |
Output:- All my Scala Examples are placed “E:>” Drive in my Windows machine.
1 2 3 4 5 6 7 |
E:>scalac Employee1.scala E:>scalac Employee1Test1.scala E:>scala Employee1Test1 From Primary Constructor From Zero-Argument Auxiliary Constructor |
By observing this output, we can say that Zero-Argument Auxiliary Constructor made a call to Primary Constructor. So it executes first Primary Constructor, then Zero-Argument Auxiliary Constructor. Because Auxiliary Constructor contains a call to Primary Constructor.
Employee1Test2.scala
1 2 3 4 5 |
object Employee1Test2 extends App{ val emp2 = new Employee1(1001, "Scala") } |
Output:-
1 2 3 4 5 6 |
<span style="color: #008000;"><strong><code> E:>scalac Employee1.scala E:>scalac Employee1Test2.scala E:>scala Employee1Test2 From Primary Constructor </code></strong></span> |
javap output:-
1 2 3 4 5 6 7 8 9 10 11 |
E:>scalac Employee1.scala E:>javap Employee1.class Compiled from "Employee1.scala" public class Employee1 { public int empId(); public java.lang.String empName(); public Employee1(int, java.lang.String); public Employee1(); } |
Example-2:-
Create a Scala class with one Primary Constructor and Multiple Auxiliary Constructors.
Employee2.scala
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Employee2(val empId : Int, val empName:String){ println("From Primary Constructor") def this(){ this(0,null) println("From Zero-Argument Auxiliary Constructor") } def this( empId : Int){ this(empId, null) println("From One-Argument Auxiliary Constructor") } } |
Here we have developed a Scala Program with one Primary Constructor and two Auxiliary Constructors.
Test Employee2.scala:-
To test the about program, we are going to write some sample examples as shown below:
Employee2Test1.scala
1 2 3 4 5 |
object Employee2Test1 extends App{ val emp21 = new Employee2 } |
Output:- All my Scala Examples are placed “E:>” Drive in my Windows machine.
1 2 3 4 5 6 7 |
E:>scalac Employee2.scala E:>scalac Employee2Test1.scala E:>scala Employee2Test1 From Primary Constructor From Zero-Argument Auxiliary Constructor |
Here we are making a call to Zero-Argument Auxiliary Constructor. It has a call to Primary Constructor so that we are seeing output both from Primary Constructor and Zero-Argument Auxiliary Constructor.
Employee2Test2.scala
1 2 3 4 5 |
object Employee2Test2 extends App{ val emp22 = new Employee2(1001) } |
Output:- All my Scala Examples are placed “E:>” Drive in my Windows machine.
1 2 3 4 5 6 7 |
E:>scalac Employee2.scala E:>scalac Employee2Test2.scala E:>scala Employee2Test2 From Primary Constructor From One-Argument Auxiliary Constructor |
Here we are making a call One-Argument Auxiliary Constructor. It has a call to Primary Constructor so that we are seeing output both from Primary Constructor and One-Argument Auxiliary Constructor.
Employee2Test3.scala
1 2 3 4 5 |
object Employee2Test3 extends App{ val emp23 = new Employee2(1001, "Scala") } |
Output:- All my Scala Examples are placed “E:>” Drive in my Windows machine.
1 2 3 4 5 6 |
E:>scalac Employee2.scala E:>scalac Employee2Test3.scala E:>scala Employee2Test3 From Primary Constructor |
Here we are calling Primary Constructor directly so that we are seeing output only from that constructor.
javap output:-
1 2 3 4 5 6 7 8 9 10 11 12 |
E:>scalac Employee2.scala E:>javap Employee2.class Compiled from "Employee2.scala" public class Employee2 { public int empId(); public java.lang.String empName(); public Employee2(int, java.lang.String); public Employee2(); public Employee2(int); } |
Important Point to Remember:-
NOTE:-In all examples in this post, Auxiliary Constructors are making a call to Primary Constructor only. However, they can make a call to previous defined other Auxiliary Constructors too.
Scala Auxiliary Constructor Rules
In Scala Programming, we need to follow these rules to define Auxiliary Constructors:
- Like Methods, Auxiliary Constructors are defined by using “def” keyword.
- Like Method Overloading, All Auxiliary Constructors should use same name: “this”.
- Each Auxiliary Constructor must have a different signature i.e. Different Parameters list.
- Each Auxiliary Constructor must call a previously defined constructor: it may be either Primary Constructor or Auxiliary Constructors. This call should be first statement in that Constructor.
- One Auxiliary Constructor calls Primary Constructor or another Auxiliary constructors by using “this” name.
Constructor Overloading With Auxiliary constructors
So for, we have discussed about “How to develop Constructors Overloading using Auxiliary constructors”. But my question is that “Is it possible to provide Constructors Overloading without using Auxiliary constructors”? Is it possible to overload constructors just by using Primary Constructor.
Thanks to Scala’ New Feature. Yes, it is possible. Let us explore this concept in this section.
We can use “Scala’s Default Arguments concept” to solve this problem. Scala has introduced this feature in Scala Version 2.9.
Example:-
Let us re-write same Employee class with Primary Constructor and Default Arguments, without using Auxiliary constructors.
Employee3.scala
1 2 3 4 5 |
class Employee3(val empId : Int = 0, val empName:String = "No-Name"){ println("From Primary Constructor") } |
If we execute this example in Scala REPL, we can see the following output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
scala> class Employee3(val empId : Int = 0, val empName:String = ""){ | println("From Primary Constructor") | println("Empid = " + (empId == 0)) | println("Empname = " + empName.isEmpty) | } defined class Employee3 scala> var e31 = new Employee3 From Primary Constructor Empid = true Empname = true e31: Employee3 = Employee3@78d6692f scala> var e32 = new Employee3(1003) From Primary Constructor Empid = false Empname = true e32: Employee3 = Employee3@1e097d59 scala> var e33 = new Employee3(1004,"Scala Play") From Primary Constructor Empid = false Empname = false e33: Employee3 = Employee3@554e218 |
We can observe that with only one Primary Constructor, we have implemented “Constructors Overloading”.
NOTE:-
Please go through my previous post at “Named Parameters and Default Parameter Values In Scala” to learn more about Scala’s Default Parameters concept.
That’s it all about Scala Auxiliary Constructors. We will discuss “How Scala Constructors work in Inheritance” concept in my coming posts.
Please drop me a comment if you like my post or have any issues/suggestions.