Kotlin tutorial for Beginners – Kotlin Constructors

Kotlin Constructors

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.

A constructor is a concise way to initialize class properties.

It is a special member function that is called when an object is instantiated (created). However, how they work in Kotlin is slightly different.

In Kotlin, there are two constructors:

  • Primary constructor – concise way to initialize a class
  • Secondary constructor – allows you to put additional initialization logic

Primary Constructor

The primary constructor is part of the class header. Here’s an example:

class Person(val firstName: String, var age: Int) {
    // class body
}

The block of code surrounded by parentheses is the primary constructor: (val firstName: String, var age: Int).

The constructor declared two properties: firstName (read-only property as it’s declared using keyword val) and age (read-write property as it is declared with keyword var).


Example: Primary Constructor


fun main(args: Array<String>) {

    val person1 = Person("Joe", 25)

    println("First Name = ${person1.firstName}")
    println("Age = ${person1.age}")
}

class Person(val firstName: String, var age: Int) {

}

When you run the program, the output will be:

First Name = Joe
Age = 25

When the object of Person class is created, "Joe" and 25 values are passed as if Person is a function.

This initializes firstName and age properties of person1 object to "Joe" and 25 respectively.


There are other ways of using primary constructors.


Primary Constructor and Initializer Blocks

The primary constructor has a constrained syntax, and cannot contain any code.

To put the initilization code (not only code to initialize properties), initializer block is used. It is prefixed with init keyword. Let’s modify the above example with initializer block:

 


fun main(args: Array<String>) {
    val person1 = Person("joe", 25)
}

class Person(fName: String, personAge: Int) {
    val firstName: String
    var age: Int

    // initializer block
    init {
        firstName = fName.capitalize()
        age = personAge

        println("First Name = $firstName")
        println("Age = $age")
    }
}

When you run the program, the output will be:

First Name = Joe
Age = 25

Here, parameters fName and personAge inside the parenthesis accepts values "Joe" and 25 respectively when person1 object is created. However, fName and personAge are used without using var or val, and are not properties of the Person class.

The Person class has two properties firstName, and age are declared.

When person1 object is created, code inside initializer block is executed. The initializer block not only initializes its properties but also prints them.


Here is another way to perform the same task:

fun main(args: Array<String>) {
    val person1 = Person("joe", 25)
}

class Person(fName: String, personAge: Int) {
    val firstName = fName.capitalize()
    var age = personAge

    // initializer block
    init {
        println("First Name = $firstName")
        println("Age = $age")
    }
}

To distinguish the constructor parameter and property, different names are used (fName and firstName, and personAge and age). It’s more common to use _firstName and _age instead of completely different name for constructor parameters. For example:

class Person(_firstName: String, _age: Int) {
    val firstName = _firstName.capitalize()
    var age = _age

    // initializer block
    init {
        ... .. ...
    }
}

Default Value in Primary Constructor

You can provide default value to constructor parameters (similar to providing default arguments to functions). For example:

fun main(args: Array<String>) {

    println("person1 is instantiated")
    val person1 = Person("joe", 25)

    println("person2 is instantiated")
    val person2 = Person("Jack")

    println("person3 is instantiated")
    val person3 = Person()
}

class Person(_firstName: String = "UNKNOWN", _age: Int = 0) {
    val firstName = _firstName.capitalize()
    var age = _age

    // initializer block
    init {
        println("First Name = $firstName")
        println("Age = $agen")
    }
}

When you run the program, the output will be:

First Name = Joe
Age = 25

person2 is instantiated
First Name = Jack
Age = 0

person3 is instantiated
First Name = UNKNOWN
Age = 0

Kotlin Secondary Constructor

In Kotlin, a class can also contain one or more secondary constructors. They are created using constructor keyword.

Secondary constructors are not that common in Kotlin. The most common use of secondary constructor comes up when you need to extend a class that provides multiple constructors that initialize the class in different ways. Be sure to check Kotlin Inheritance before you learn it.

Here’s how you can create a secondary constructor in Kotlin:

class Log {
    constructor(data: String) {
        // some code
    }
    constructor(data: String, numberOfData: Int) {
        // some code
    }
}

Here, the Log class has two secondary constructors, but no primary constructor.

You can extend the class as:

class Log {
    constructor(data: String) {
        // code
    }
    constructor(data: String, numberOfData: Int) {
        // code
    }
}

class AuthLog: Log {
    constructor(data: String): super(data) {
        // code
    }
    constructor(data: String, numberOfData: Int): super(data, numberOfData) {
        // code
    }
}

Here, constructors of the derived class AuthLog calls the corresponding constructor of the base class Log. For that, super() is used.

Calling constructor of base class from derived class.

In Kotlin, you can also call a constructor from another constructor of the same class (like in Java) using this().

class AuthLog: Log {
    constructor(data: String): this(data, 10) {
        // code
    }
    constructor(data: String, numberOfData: Int): super(data, numberOfData) {
        // code
    }
}
Calling constructor from the same class.

Example: Kotlin Secondary Constructor

fun main(args: Array<String>) {

    val p1 = AuthLog("Bad Password")
}

open class Log{
    var data: String = ""
    var numberOfData = 0
    constructor(_data: String) {

    }
    constructor(_data: String, _numberOfData: Int) {
        data = _data
        numberOfData = _numberOfData
        println("$data: $numberOfData times")
    }
}

class AuthLog: Log {
    constructor(_data: String): this("From AuthLog -> " + _data, 10) {
    }

    constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) {
    }
}

When you run the program, the output will be:

From AuthLog -> Bad Password: 10 times

 

 

Python Example for Beginners

Two Machine Learning Fields

There are two sides to machine learning:

  • Practical Machine Learning:This is about querying databases, cleaning data, writing scripts to transform data and gluing algorithm and libraries together and writing custom code to squeeze reliable answers from data to satisfy difficult and ill defined questions. It’s the mess of reality.
  • Theoretical Machine Learning: This is about math and abstraction and idealized scenarios and limits and beauty and informing what is possible. It is a whole lot neater and cleaner and removed from the mess of reality.

Data Science Resources: Data Science Recipes and Applied Machine Learning Recipes

Introduction to Applied Machine Learning & Data Science for Beginners, Business Analysts, Students, Researchers and Freelancers with Python & R Codes @ Western Australian Center for Applied Machine Learning & Data Science (WACAMLDS) !!!

Latest end-to-end Learn by Coding Recipes in Project-Based Learning:

Applied Statistics with R for Beginners and Business Professionals

Data Science and Machine Learning Projects in Python: Tabular Data Analytics

Data Science and Machine Learning Projects in R: Tabular Data Analytics

Python Machine Learning & Data Science Recipes: Learn by Coding

R Machine Learning & Data Science Recipes: Learn by Coding

Comparing Different Machine Learning Algorithms in Python for Classification (FREE)

Disclaimer: The information and code presented within this recipe/tutorial is only for educational and coaching purposes for beginners and developers. Anyone can practice and apply the recipe/tutorial presented here, but the reader is taking full responsibility for his/her actions. The author (content curator) of this recipe (code / program) has made every effort to ensure the accuracy of the information was correct at time of publication. The author (content curator) does not assume and hereby disclaims any liability to any party for any loss, damage, or disruption caused by errors or omissions, whether such errors or omissions result from accident, negligence, or any other cause. The information presented here could also be found in public knowledge domains.