Site icon Experiences Unlimited

Brief insight into Constructors in Scala

In the previous post here, I had introduced few concepts related to constructors in Scala. In this post I would go a bit deeper into the constructors and how we can provide different constructors. Summarizing about the introduction in the previous post here

class Person(firstName:String, lastName:String){
  override def toString():String = firstName+" " +lastName
}

So lets add some checks for the parameters being passed- Lets say we dont want the firstName to be passed as empty string.

class Person(firstName: String, lastName: String){
  require(firstName!=null && !firstName.equals(""))
  override def toString():String = firstName+" " +lastName
}

require method defined in the Predef object is used to check for conditions. So lets try to create an instance of Person and see how this check helps:

scala> var p = new Person("","Sanaulla")
java.lang.IllegalArgumentException: requirement failed
        at scala.Predef$.require(Predef.scala:133)
        at Person.<init>(<console>:6)
        at .<init>(<console>:6)
        at .<clinit>(<console>)
        at RequestResult$.<init>(<console>:9)
        at RequestResult$.<clinit>(<console>)
        at RequestResult$scala_repl_result(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
        at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpre...
scala> var p = new Person("Mohamed","Sanaulla")
p: Person = Mohamed Sanaulla

So if we try to pass an empty string for the firstName- An IllegalArgumentException is thrown.
With the above implementation of constructor, we will not be able to access the values of firstName and lastName from outside the class. So for this, we can add 2 fields for the same:

class Person(fName:String, lName:String){
  require(firstName!=null && !firstName.equals(""))
  var firstName:String = fName //Using fields instead of construcotr params
  var lastName: String = lName
  override def toString():String = firstName+" "+lastName
}

Now lets see how we can add multiple constructors,. in other words- Auxiliary Constructors. Suppose we wanted to make the lastName as optional, in that case we can provide an auxiliary constructor which would just take one parameter- firstName. Auxiliary constructors being with: def this(<Parameter List>).

class Person(fName: String, lName:String){
  require(firstName!=null && !firstName.equals(""))
  var firstName = fName
  var lastName = lName
  def this(fName:String) = this(fName,"")//Auxiliary constructor
  override def toString():String = firstName+" "+lastName
}

We would have to note here that the first statement of auxiliary constructor must be a call to the another constructor of the same class and it should be declared before the calling constructor. In Java- the first statement would be- a call to this or super constructor, In Scala, super constructor can only be called from the primary constructor. If we analyse the methods generated in the class file of Person, we can see that there’s is an Overloaded constructor-

C:devscalablogPost>javap Person
Compiled from "OOP1.scala"
public class Person extends java.lang.Object implements scala.ScalaObject{
    public java.lang.String firstName();
    public void firstName_$eq(java.lang.String);
    public java.lang.String lastName();
    public void lastName_$eq(java.lang.String);
    public Person(java.lang.String);
    public java.lang.String toString();
    public Person(java.lang.String, java.lang.String);
}
Exit mobile version