Scala Auxiliary Constructors In-Depth

Filed Under: Scala

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


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


object Employee1Test1 extends App{
  val emp1 = new Employee1()  
}

Output:- All my Scala Examples are placed “E:\>” Drive in my Windows machine.


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


object Employee1Test2 extends App{
  val emp2 = new Employee1(1001, "Scala")  
}

Output:-


E:\>scalac Employee1.scala
E:\>scalac Employee1Test2.scala
E:\>scala Employee1Test2
From Primary Constructor

javap output:-


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


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


object Employee2Test1 extends App{
  val emp21 = new Employee2  
}

Output:- All my Scala Examples are placed “E:\>” Drive in my Windows machine.


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


object Employee2Test2 extends App{
  val emp22 = new Employee2(1001)   
}

Output:- All my Scala Examples are placed “E:\>” Drive in my Windows machine.


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


object Employee2Test3 extends App{
  val emp23 = new Employee2(1001, "Scala")   
}

Output:- All my Scala Examples are placed “E:\>” Drive in my Windows machine.


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:-


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


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:


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.

Comments

  1. vijay says:

    class Employee1(val empId : Int, val empName:String){
    println(“From Primary Constructor”)
    def this(){
    this(0,null)
    println(“From Zero-Argument Auxiliary Constructor”)
    }
    }

    If i remove this code, this(0,null)… it is not at all compiling….
    why this tight coupling, when i want to use default constructor (i.e. auxillary). ???

    1. Samuel William says:

      Every Auxillary constructor should call either primary constructor or previously defined constructor, In this case if you remove this(0,null) then it wont call the primary constructor and hence this error.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages