Kotlin Class – Kotlin Constructor

Filed Under: Kotlin

In this tutorial, we’ll be discussing the Object Oriented Programming concepts of Kotlin. We’ll discuss Kotlin Class in detail. We will also look at kotlin constructors, access modifiers and abstract class.

Kotlin Class

kotlin class, kotlin constructor

A class is a blue print defined which groups functions and properties. Classes in Kotlin are defined using the keyword class followed by the class name. The body goes inside the curly braces.


class FirstClass {
}

An instance of the class is instantiated in the following way:


val firstClass =  FirstClass()
var new = FirstClass() //here new is the name of the var.

Contrary to Java, new isn’t a keyword in Kotlin.

Classes by default are final in Kotlin.
So the equivalent of the above definitions in Java would like something like this:


public final class FirstClass {
}

Hence, by default classes in Kotlin are not inheritable.

To make a class non-final we need to append the keyword open.


open class Me{
}

The open annotation allows others to inherit from this class.

Kotlin Class Example

Let’s create a class with a few functions and a property. We’ll see how to access the functions and properties of that class. Furthermore, we’ll see how to set the member properties.


class User {

    var loggedIn: Boolean = false
    val cantChangeValue = "Hi"
    
    fun logOn() {
        loggedIn = true
    }
    
    fun logOff() {
        loggedIn = false
    }
}

fun main(args: Array<String>) {

    val user = User()
    println(user.loggedIn) //false
    user.logOn()
    println(user.loggedIn) //true
    user.logOff()
    println(user.loggedIn) //false
    user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.

}

The function main belongs to the Test.kt class. To access members and functions, we need to use the dot operator. A val property can’t be set again using a dot operator.

Kotlin init

Kotlin init block is defined as shown below.


class User {
    
    init{
        print("Class instance is initialised.")
    }

    var loggedIn: Boolean = false
    val cantChangeValue = "Hi"

    fun logOn() {
        loggedIn = true
    }

    fun logOff() {
        loggedIn = false
    }
}

The code inside the init block is the first to be executed when the class is instantiated. The init block is run every time the class is instantiated, with any kind of constructor as we shall see next.

Multiple initializer blocks can be written in a class. They’ll be executed sequentially as shown below.


class MultiInit(name: String) {

    init {
        println("First initializer block that prints ${name}")
    }

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

fun main(args: Array<String>) {
    var multiInit = MultiInit("Kotlin")
}

//Following is printed in the log console.
//First initializer block that prints Kotlin
//Second initializer block that prints 6

Kotlin classes allow printing properties in the declaration itself by using the also function as shown below.


class MultiInit(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints ${name}")
    }

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

fun main(args: Array<String>) {

    var multiInit = MultiInit("Kotlin")
}

//Following gets printed.
//First property: Kotlin
//First initializer block that prints Kotlin
//Second property: 6
//Second initializer block that prints 6

Kotlin Constructor

Kotlin Constructors are special member functions that are used to initialize properties. Constructors in Kotlin are written and structured differently compared with Java. By default a class has an empty constructor as shown below:


class Student {
    var name: String
    val age : Int

    init {
        name = "Anupam"
        age = 24
    }

    init {
        name = "Anupam Chugh"
        //age = 26
    }
}

fun main(args: Array<String>) {
    
    val student = Student()
    println("${student.name} age is ${student.age}")
    student.name = "Your"
    //student.age = 26 //won't compile. age is val
    println("${student.name} age is ${student.age}")

}

//Following is printed on the console:
//Anupam Chugh age is 24
//Your age is 24

Primary Constructors

Primary Constructors in Kotlin are defined in the class header itself as shown below.


class User(var name: String, var isAdmin: Boolean) {

    init {
        name = name + " @ JournalDev.com"
        println("Author Name is $name. Is Admin? $isAdmin")
    }
}

The primary constructors definition goes inside the class header. We’ve defined the property types(val/var) in the constructor itself.

Note: Unless stated as a var, by default, constructor arguments are val.


class User(name: String, isAdmin: Boolean)

In the above code, both name and isAdmin can’t be reassigned.

Alternatively, we can aslo assign the constructor arguments to the member properties in the class as shown below.


class User(name: String, val isAdmin: Boolean) {

    var username  = name
    val _isAdmin = isAdmin

    init {
        username= username + " @ JournalDev.com"
        println("Author Name is $name. Is Admin? $_isAdmin")
    }
}

fun main(args: Array<String>) {

    var user = User("Anupam",false)
    user.isAdmin = true //won't compile since isAdmin is val
    user._isAdmin = true //won't compile. Same reason.
    user = User("Pankaj",true)
}

//Following is printed in the log console.
//Author Name is Anupam. Is Admin? false
//Author Name is Pankaj. Is Admin? true

Kotlin Constructor Default Values

Kotlin allows us to specify default values in the constructor itself as shown below.


class User(name: String, var website: String = "JournalDev") {

    init {
        println("Author $name writes at $website")
    }

    init {
        website = website + ".com"
        println("Author $name writes at $website")
    }
}

fun main(args: Array<String>) {

    var user = User("Anupam","JournalDev")
    user = User("Pankaj","JournalDev")
}

//Following is printed on the console:
//Author Anupam writes at JournalDev
//Author Anupam writes at JournalDev.com
//Author Pankaj writes at JournalDev
//Author Pankaj writes at JournalDev.com

Secondary Constructors

Secondary Constructors are written inside the body of the class by prefixing with the keyword constructor. Following example demonstrates the same.


class Student {
    var name: String
    val age : Int

    constructor(name: String, age: Int)
    {
        this.name = name
        this.age = age
    }

    fun printDetails()
    {
        println("Name is $name and Age is $age")
    }

}

fun main(args: Array<String>) {

    var student = Student("Anupam", 24)
    student.printDetails()
}

//Following is printed in the console.
//Name is Anupam and Age is 24

The most common usage of secondary constructors comes in subclasses when you need to initialize the class in different ways.

If the class contains a primary constructor, the secondary constructor must refer to it in its declaration. The declaration is done using this keyword.


class Student(var name: String, val age: Int) {

    var skill: String

    init {
        skill = "NA"
    }

    constructor(name: String, age: Int, skill: String) : this(name, age) {
        this.skill = skill
    }

    fun printDetails() {
        if (skill.equals("NA"))
            println("Name is $name and Age is $age")
        else
            println("Name is $name and Age is $age Skill is $skill")
    }
}

//Following is printed in the log console:
//Name is Anupam and Age is 24
//Name is Anupam and Age is 24 Skill is Kotlin

init block is used to initialise the member property skill. The secondary constructor delegates to the primary constructor using : this.

Custom Getter and Setters

Up until now we’ve accessed and modified properties in a class using the dot operator on the instance of the class. Let’s use set and get syntax to see how we can customise the access.


class Name{
    var post: String = "default"
    set(value) {if(!post.isNotEmpty()) {
        throw IllegalArgumentException(" Enter a valid name")
    }
                field = value
                print(value)
    }

}

fun main(args: Array<String>) {

    var name = Name()
    name.post = "Kotlin Classes"
    name.post = ""
    name.post = "Kotlin Data Classes Our Next Tutorial"


}

Following is printed in the log console:


Kotlin Classes

Exception in thread "main" java.lang.IllegalArgumentException:  Enter a valid name
	at Name.setPost(Test.kt:16)
	at TestKt.main(Test.kt:78)

The field variable in the setter saves the older value. Let’s add a getter.


class Name{
    var post: String = "default"
    set(value) {if(!post.isNotEmpty()) {
        throw IllegalArgumentException(" Enter a valid name")
    }
                field = value
    }
    get() {
        return field.capitalize()
    }

}

fun main(args: Array<String>) {

    var name = Name()
    name.post = "kotlin classes"
    println(name.post)
    name.post = "kotlin data Classes our next Tutorial"
    println(name.post)

}

//Following is printed:
//Kotlin classes
//Kotlin data Classes our next Tutorial

capitalize() capitalizes the first letter of the string.

Note: if the property is a val, set method won’t compile.

Kotlin Visibility Modifier

  • Public : Any class, function, property, interface, or object that has this modifier is visible and can be accessed from anywhere.
  • Private: A class/function defined with this modifier can be only accessed within the same file. A member/property in a class/function with this modifier can be only accessed within that block.
  • Protected : This modifier is same as private, except that it allows visibility and access within subclasses.
  • Internal: A class/interface/function with this modifier is accessible only within the same module.

Visibility Modifiers are applicable on Constructors as well. Assigning a modifier to a Primary Constructor requires us to specify the keyword constructor alongside the constructor in the class header.


class Student private constructor (var name: String, val age: Int) {

    var skill: String

    init {
        skill = "NA"
    }

    constructor(name: String, age: Int, skill: String) : this(name, age) {
        this.skill = skill
    }

    fun printDetails() {
        if (skill.equals("NA"))
            println("Name is $name and Age is $age")
        else
            println("Name is $name and Age is $age Skill is $skill")
    }
}

fun main(args: Array<String>) {

    var student = Student("Anupam",24,"Kotlin")
    student.printDetails()
}

//prints
//Name is Anupam and Age is 24 Skill is Kotlin

Private constructors can’t be called outside the class. In the above code, we can instantiate the class in a different function only using the secondary constructor.

Kotlin Abstract Class

Like Java, abstract keyword is used to declare abstract classes in Kotlin. An Abstract class can’t be instantiated. However, it can be inherited by subclasses. By default, the members of an abstract class are non-abstract unless stated otherwise.


abstract class Person(name: String) {

    init {
        println("Abstract Class. init block. Person name is $name")
    }

    abstract fun displayAge()
}

class Teacher(name: String): Person(name) {

    var age : Int

    init {
        age = 24
    }

    override fun displayAge() {
        println("Non-abstract class displayAge function overridden. Age is $age")
    }
}

fun main(args: Array<String>) {

    val person = Teacher("Anupam")
    person.displayAge()

}

//Following is printed in the console.
//Abstract Class. init block. Person name is Anupam
//Non-abstract class. Age is 24

Note: Abstract classes are by default open. So adding an open modifier to allow subclassing isn’t required.

override keyword is used to override a method in the subclass.

We’ve covered the basics of kotlin classes in this tutorial. There’s a lot more still there such as Data Classes, Sealed Classes, Inheritance etc. We’ll be covering them in the upcoming tutorials.

References : Kotlin Docs

Comments

  1. Aniket Malviya says:

    Explained nicely.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages