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.