Kotlin Constructor

In this article, you will learn about constructors in Kotlin (both primary and secondary constructors) as well as initializer blocks with the help of examples.

Constructor

  • A constructor for a class is a special member function, mainly used to initialize the properties of the newly created object of that class type.
  • It is called implicitly, just after the memory is allocated for the object.
  • It is not mandatory for the programmer to write a constructor for a class.
  • When there is no constructor defined in the class by the programmer, the compiler implicitly provides a default constructor for the class.
  • In Kotlin, the default visibility of the constructor is public. However, the visibility can be changed to private, protected or internal.

Types of Constructor

In Kotlin, there are two types of constructors:

  • Primary constructor –  initializes the class.
  • Secondary constructor – initializes the class and allows you to put additional logic.

Primary Constructor

The primary constructor is part of the class header (contains the type parameters, the primary constructor, etc.), goes after the class name, using the constructor keyword.

In Kotlin, a class can have at most one primary constructor and the parameters are optional.

//Addition is the class_name
//constructor(val a: Int, val b: Int) is the class_header
class Addition constructor(var a: Int, var b: Int) {
    //body of class
}

The constructor keyword can be omitted if there is no annotation or visibility modifier specified.

//constructor keyword optional
//without annotation or access modifier
class Addition(val a: Int, val b: Int) {
    // body of class
}

//constructor keyword is needed
//with annotation or access modifier
class Addition private @Inject constructor(val a: Int, val b: Int) {
   // body of class
}
Example: Primary constructor
//main function
fun main(args: Array<String>) {
    var person = Person("Arun", 28)
    println("FirstName: ${person.pers_fname} \n Age: ${person.pers_age}")
}

//primary constructor
//constructor keyword is optional
class Person constructor(val pers_fname: String, var pers_age: Int) {
}
Output
FirstName: Arun
Age: 28
Example explained
  • When the object of Person class is created,  values “Arun” and 28 gets passed to the constructor.
  • The constructor parameters pers_fname and pers_age get initialized with the values Arun and 28 respectively.
  • Inside main(), we can directly access the constructor parameters just like we access class properties.

Primary Constructor with Initializer Block

The primary constructor cannot contain any code, the initialization code can be placed in a separate initializer block prefixed with the init keyword.

Example 
//main function
fun main(args: Array<String>) {
    var person = Person("Arun", 28)
}

//primary constructor
class Person constructor(pers_fname: String, pers_age: Int) {

    val firstName: String
    var age: Int

    // initializer block
    init {
        firstName = pers_fname
        age = pers_age

        println("FirstName: $firstName")
        println("Age: $age")
    }
}
Output
FirstName: Arun
Age: 28
Example explained
  • When the object person is created for the class Person, the values “Arun” and 28 gets passed to the parameter pers_fname and pers_age of the constructor.
  • firstName and age are the two properties of Person class.
  • Initializer block is executed at the time of object creation, and not only initialize the properties but also prints to the standard output.

Default values in Primary Constructor 

You need not pass all the parameters while declaring an object. You can initialize the constructor parameters with some default values.

Example 
//main function
fun main(args: Array<String>) {
    var person1 = Person("Ronald", 28)
   //default value for age will be used here
    var person2 = Person("Rohit")
   //default values for both parameters is used because no arguments passed 
    var person3 = Person()

}

//primary constructor
class Person constructor(pers_fname: String = "Arun", pers_age: Int = 26) {

    val firstName: String
    var age: Int

    // initializer block
    init {
        firstName = pers_fname
        age = pers_age

        println("FirstName: $firstName , Age: $age")
        
    }
}
Output
FirstName: Ronald , Age: 28
FirstName: Rohit , Age: 26
FirstName: Arun , Age: 26
Example explained
  • Here, we have initialized the constructor parameters with some default values pers_fname = “Arun” and pers_age = 26.
  • So, whenever we skip the parameter values while creating objects, the compiler will automatically initialize the object properties with the default values.

Secondary Constructor

Secondary constructor initializes the class (properties) and allows you to put additional logic to the class as well.

They are prefixed with the constructor keyword and are written inside the body of class.

In Kotlin, a class may have one or more secondary constructors and which secondary constructor will be called is decided by the compiler based on the arguments received.

Example: Secondary constructor
fun main(args: Array<String>) {
    Addition(2, 3)
    Addition(2, 3, 4)
    Addition(2, 3, 4, 5)
}

//class with three secondary constructors
class Addition {
//secondary constructor with two arguments
    constructor(a: Int, b: Int) {
        var c = a + b
        println("Sum of 2, 3 : ${c}")
    }
//secondary constructor with three arguments
    constructor(a: Int, b: Int, c: Int) {
        var d = a + b + c
        println("Sum of 2, 3, 4 : ${d}")
    }
//secondary constructor with four arguments
    constructor(a: Int, b: Int, c: Int, d: Int) {
        var e = a + b + c + d
        println("Sum of 2, 3, 4, 5 : ${e}")
    }
}
Output
Sum of 2, 3 : 5
Sum of 2, 3, 4 : 9
Sum of 2, 3, 4, 5 : 14
Example explained
  • Firstly, the secondary constructor (with two arguments) is called, which prints the sum of two numbers.
  • Then,  the secondary constructor (with three arguments) is called, which prints the sum of three numbers.
  • And then, the secondary constructor (with four arguments) is called, which prints the sum of four numbers.

Calling one Secondary constructor from another

A secondary constructor may call another secondary constructor of the same class using this keyword.

Example 
fun main(args: Array<String>) {
    Addition(2, 3)
}

class Addition {
    constructor(a: Int, b: Int) : this(a, b, 4) {
        var sumOfTwo = a + b
        println("The Sum of two numbers 2, 3 is: ${sumOfTwo}")
    }

    constructor(a: Int, b: Int, c: Int) {
        var sumOfThree = a + b + c
        println("The Sum of three numbers 2, 3, 4 is: ${sumOfThree}")
    }

}
Output
The Sum of three numbers 2, 3, 4 is: 9
The Sum of two numbers 2, 3 is: 5
Example explained
  • Inside Addition class, the secondary constructor (with two arguments) is calling the secondary constructor (with three arguments) using this keyword.
  • So, the compiler will first execute secondary constructor (with three arguments) then secondary constructor (with two arguments).

Calling parent class secondary constructor from child class secondary constructor 

We can call the secondary constructor of the parent class from the child class using the super keyword.

Example 
fun main(args: Array<String>) {
    Child("Arun", "Verma")
}

open class Parent {
    constructor (pers_fname: String, pers_lname: String, pers_age: Int) {
        var firstName: String = pers_fname
        var lastName: String = pers_lname
        var age: Int = pers_age
        print("FirstName : $firstName, ")
        print("LastName: $lastName, ")
        println("Age: $age")

    }
}

class Child : Parent {
    constructor (pers_fname: String, pers_lname: String) : super(pers_fname, pers_lname, 26) {
        var firstName: String = pers_fname
        var lastName: String = pers_lname
        print("FirstName: $firstName, ")
        println("LastName: $lastName")
    }
}
Output
FirstName : Arun, LastName: Verma, Age: 26
FirstName: Arun, LastName: Verma
Example explained
  • Inside Child class, secondary constructor (with two arguments) is calling Parent class secondary constructor (with three arguments) using super keyword.
  • So, the compiler will first execute Parent class secondary constructor then Child class secondary constructor.

 

Leave a Reply