Kotlin Inheritance

This post is about inheritance in Kotlin. Inheritance is an important object-oriented programming concept. Read my post on object-oriented programming, and on classes before reading this. If you already have an idea about classes and inheritance, then continue reading.

kotlin inheritance
kotlin inheritance

You already know what classes and objects are. Now, inheritance is nothing but inheriting the properties and functions of a class by another class. The inherited class is called child class and the class from which inherited is called base class, parent class, or super class. So, the inherited class will have all the properties and functions of the parent class. It can define some of its own and may override some of the properties or functions of its parent class. Kotlin offers total flexibility to the programmers to do what they want, as long as the parent class permits it.

Why should we use inheritance

To understand the power of inheritance, let’s look at this situation. One class is defined in a library. You need to use it with some added features. If it wasn’t for inheritance, you would have to copy the entire code in your class and add the features you want. How cumbersome it would be!! Inheritance is a lifesaver in these kinds of scenarios. You only need to extend the class you want.

Inheritance is really useful when the base class is written by someone else and you need to use it with some modifications. You’ll do this
often when you program in the real world.

Now let’s see some examples:

class Base1(var prop1:Int, var prop2:Int){
    fun printValues(){
        println("Property1 : $prop1")
        println("Property2 : $prop2")
    }
}

//Error : Error: This type is final, so it cannot be inherited from

class Child1(var bprop1:Int, var bprop2:Int) : Base1(bprop1,bprop2){
    fun printWelcome(){
        println("Hello, this is an additional function defined in child class")
    }
}

You can see that the code won’t compile. We can’t inherit from the class Base1. Why? Because it’s a final class. What does that mean?
It means that the definition of the class is final and we can’t extend the class. So, what should we do to make our classes ‘inheritable’? We need to make them open. We can make a class open by adding the keyword open before class.

So, our code will look something like this:

open class Base1(var prop1: Int, var prop2: Int) {
    fun printValues() {
        println("Property1 : $prop1")
        println("Property2 : $prop2")
    }
}

class Child1(bprop1: Int, bprop2: Int) : Base1(bprop1, bprop2) {
    fun printWelcome() {
        println("Hello, this is an additional function defined in child class")
    }
}

fun main() {
    val obj1 = Child1(11, 22)
    obj1.printWelcome()
    obj1.printValues()
}

We’ve made the Base1 class open, meaning, we can extend it. Or in other words other classes can inherit from it.

The function has two properties prop1 and prop2 and one function printValues() defined in it.

Now we define a second function named Child1 and it’s extending the Base1 class. So it automatically inherits all the properties and functions of the base class.

As the Child1 is inheriting from Base1 class, it has all the properties and functions of the parent class. So, the Child1 class already contains two properties and one function implicitly.

We’re adding one more function to the Base1 class, function named printWelcome(). It does nothing but prints a message to the screen. Thus, the Base1 class now contains two properties and two functions.

Many number of classes can be inherited from one Base class

open class A
class B : A()
class C : A()
class D : A()

Here the classes B, C, and D inherit from A.

Overloading Functions

The child classes can define functions which are of the same name as functions in the parent class. Then overloading of function happens. The function signature has to be different for overloading to occur. The call resolution is the same as described in this post.

open class A(var prop1: Int, var prop2: Int) {
    fun calcVal(num:Int){
    println("A's function")
    println("Calculated value = ${num*(prop1+prop2)}")
}
}
class B(var bprop1: Int, var bprop2:Int) : A(bprop1,bprop2){
    fun calcVal(num:Double){

        println("B's function")
        println("Calculated value = ${num*(prop1+prop2)}")
    }
}

fun main() {
    val obj1 = A(4,5)
    val obj2 = B(4,5)
    obj1.calcVal(12)
    obj2.calcVal(12)
    obj2.calcVal(12.0)
    
}

Overriding Functions

We can override functions defined in the parent class. That means the function in the parent class is masked by the new function defined in the subclass. Whenever an object of child class calls the function which is overridden, the function defined in the child class gets called. In Kotlin, we override function with the keyword override.

open class Base1(var prop1: Int, var prop2: Int) {
    open fun printValues() {
        println("Property1 : $prop1")
        println("Property2 : $prop2")
    }
}

class Child1(bprop1: Int, bprop2: Int, var bprop3:String) : Base1(bprop1, bprop2) {
    fun printWelcome() {
        println("This is an additional function defined in child class")
    }
    override fun printValues(){
        super.printValues()
        println("Property3 : $bprop3")
    }

Use of keyword super

The keyword – super is used to refer to the functions in the superclass (parent class). See the previous example program. We used the statement super.printValues(). It means we are calling the printValues() function of the superclass. And then, we added a line to print the value of bprop3. What the compiler does is, it executes the function defined in the superclass and then executes the line after that. These together constitute the printValues() function of the subclass.

Hope you got a basic idea of inheritance in Kotlin from this post. Inheritance in Kotlin is a very powerful feature. We’ll see more about inheritance as we learn and program more.


Comments and feedback are welcome as always. đŸ™‚

« Back to the index of Kotlin tutorial

Please follow and like us:

Leave a Reply