Primary and Auxiliary Constructors in Scala

Constructors in Scala are a bit different than in Java. Scala has 2 types of constructors:

  • Primary Constructor
  • Auxiliary Constructor

also read:

Primary Constructor

In Java we have a no-args default constructor which is provided for every class which doesn’t provide its own constructor methods. On a similar lines Primary Constructor in Scala is the kind-of default constructor in the way every class in Scala would have a Primary Constructor.

The primary constructor spans the complete class definition i.e in the example below the age field gets initialized as part of the Primary Constructor of the Employee class.

class Employee{
  var age:Int = 20
}

In the above example the primary constructor didn’t accept any parameters. But the primary constructor can also accepts parameters, this is where it is different from default constructors in Java. Let me not try to draw an analogy any further.

class Employee(val firstName:String,
               val lastName:String){

  override def toString():String = {

    "First Name: "+firstName+" Last Name: "+lastName
  }
}

Auxiliary Constructor

In Java one can overload the constructors to provide different constructors accepting different parameters. On similar lines Scala classes can declare Auxiliary constructors which are overloaded forms of the Primary Constructor. The auxiliary constructors are named as this.
Lets see an example:

class Employee(val firstName:String, val lastName:String){
  var age:Int = 0

  //Auxiliary Constructor
  def this(firstName:String, lastName: String, age:Int){

    this(firstName,lastName)
    this.age = age

  }

  override def toString():String = {
    "First Name: "+firstName+" Last Name: "+lastName
  }

}

There’s a catch here- The auxiliary constructor can invoke the primary constructor or an auxiliary constructor declared just before it, which means the below code will not work:

class Employee(val firstName:String, val lastName:String){
  var age:Int = 0
  var city:String = _

  def this(firstName:String, lastName: String,
           city:String, age:Int){
    this(firstName, lastName, city)
    this.age = age

  }
  def this(firstName:String, lastName: String, city:String){
    this(firstName,lastName)
    this.city = city

  }

  override def toString():String = {
    "First Name: "+firstName+" Last Name: "+lastName
  }

}

Trying to compile the above code results in:

$ scalac Employee.scala
Employee.scala:9:error: called constructor's definition must
precede calling constructor's definition
    this(firstName, lastName, city)
    ^
one error found

The error clearly says what’s wrong. One would have to take care of this, though the compiler would report such issues, but its always good to know.

Comments

comments

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Comments

  1. Two design ideas. First idea: Using a companion object may work around the situation of one auxiliary calling others. In this case, putting multiple definitions of the method would provide multiple constructors with different signature. Second: ordering constructors from the one taking the least arguments to the more complex would let the class choose the right definition.

Trackbacks

  1. [...] can invoke the primary constructor which in turn would invoke the Super class constructor. Read here to know more about Primary and Auxiliary constructors in [...]

Speak Your Mind

*