Signup/Sign In

Kotlin Inheritance

In this tutorial we will learn the concept of Inheritance in Kotlin, which is a major feature of Object Oriented Programming. We will learn how we can implement inheritance in classes in Kotlin, how primary and secondary constructors act in Inheritance, and we will learn about overriding methods and properties of class.

What is Inheritance?

Inheritance is one of the most important features of object-oriented programming. It allows one class to inherit features of another class.

Suppose you created a class Vehicle which has properties and methods related to vehicles. Now we need to create another class Car which has many properties common to vehicles. So instead of re-writing the same code, we can inherit Vehicle class in Car class. Similarly, we can create a class TwoWheeler which again can inherit some basic common properties from the Vehicle class and can have some properties of its own.

This way, Inheritance can be used to divide code properly, enabling re-use of code and providing more structure to the code.

Inheritance allows the new class to inherit properties and methods of an existing class. The existing class or the class from which new class is inherited is known as the base class or parent class or super class. The new class which inherits the features of existing class is known as derived class or child class or sub class.

Inheritance in Kotlin

All classes in Kotlin are by default final. It means these classes are not inheritable. To make a class inheritable, we add open keyword in the class header.

A child class inherits a parent class using : operator. The syntax to inherit a class is:

open class Parent{
    // Parent class features
}
class Child : Parent(){
    // Child class features
}

Let us create a very basic example of inheritance:

// parent class
open class Vehicle{
    fun run(){
        println("Vehicle runs....")
    }
}
// child class
class Car : Vehicle(){
    fun seats(){
        println("Car has 4 seats")
    }
}

fun main() {
    val car = Car()
    car.seats()
    // calling method defined in parent class
    car.run()
}


Car has 4 seats
Vehicle runs....

In this example we've marked the class Vehicle as open to make it inheritable. The class Car inherits the class Vehicle and thus inherit its function run().

In Kotlin, a class can only inherit one class, which is same as Java. Thus, Kotlin doesn't allow multiple inheritance. But a class can implement many interfaces which we will discuss in next tutorials.

Primary constructor in Inheritance

If the parent class has a primary constructor then the child class must call the primary constructor of parent class. In the example above, in the Car class we've also called primary constructor of Vehicle class (the primary constructor was created by compiler as we haven't provide one). Let us pass properties to the parent class and see how they work.

/*
  Vehicla class has properties:
     - is the vehicle for carrying passengers
     - no. of tyres
     - fuel capacity of vehicle
*/
open class Vehicle(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int){
    init {
        println("Does Vehicle carry passenger: $carryPassenger")
        println("Tyres in Vehicle: $tyres")
        println("Fuel capacity of Vehicle: $fuelCapacity")
    }
}

// child class with extra airBags property
class Car(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int, airBags: Int) : Vehicle(carryPassenger, tyres, fuelCapacity){
    // init function for child class
    init {
        println("No. of air bags in car: $airBags")
    }
}

fun main() {
    val car = Car(true, 4, 50, 4)
}


Does Vehicle carry passenger: true
Tyres in Vehicle: 4
Fuel capacity of Vehicle: 50
No. of air bags in car: 4

In this example, we passed values while creating the object of the child class. From these properties, we passed carryPassenger, tyres and fuelCapacity to the primary constructor of parent class Vehicle.

While creating the object of Car class, the primary constructor(default) of the child class which is Car is called which internally calls the primary constructor of parent class Vehicle first and then its init block. After that, the primary default constructor of the child class Car completes and then the init block of child class Car is executed.

Secondary constructor in Inheritance

If the base class does not have a primary constructor but has a secondary constructor then the derived class should call the secondry constructor of the base class using the super keyword.

open class Vehicle{
    // secondary constructor
    constructor(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int){
        println("Does Vehicle carry passenger: $carryPassenger")
        println("Tyres in Vehicle: $tyres")
        println("Fuel capacity of Vehicle: $fuelCapacity")
    }
}
// child class
class Truck: Vehicle{
    // secondary constructor calling super for parent class
    constructor(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int, loadCarryCapacity: Int): super(carryPassenger, tyres, fuelCapacity){
        println("Load carrying capacity is: $loadCarryCapacity")
    }
}

fun main() {
    val truck = Truck(false, 10, 200, 1000)
}


Does Vehicle carry passenger: false
Tyres in Vehicle: 10
Fuel capacity of Vehicle: 200
Load carrying capacity is: 1000

In this example, the secondary constructor of Truck class called the secondary constructor of Vehicle class using super keyword. All the required arguments for parent class are provided while calling through super.

Kotlin Function Overriding

In inheritance, we can provide specific implementation of the base class functions inside the derived class. It means if a function exists in parent class then we can provide a different implementation of the same function in child class. It is known as Function Overriding.

In Kotlin, the functions are also final by default. To override a function, it must be marked as open(just like the class) in the parent class and in the child class we must use the keyword override instead of open to specify that we have overridden the function.

The function name and parameters should be same.

And, the return type of child class functions can be a sub type of the parent class functions.

Let us see an example in which we will override two methods of the base class:

// parent class
open class Vehicle{

    open fun run(){
        println("Vehicle is running")
    }

    open fun drivenBy(name: String){
        println("Vehicle is driven by: $name")
    }
}
// child class
class Jeep: Vehicle(){

    override fun run() {
        println("Driving a Jeep")
    }

    override fun drivenBy(name: String) {
        println("Jeep is driven by $name")
    }
}

fun main() {
    val jeep = Jeep()
    jeep.run()
    jeep.drivenBy("Ninja")
}


Driving a Jeep
Jeep is driven by Ninja

In this example, we override two methods run() and drivenBy() of Vehicle class and override them in Jeep class.

We can also call parent class functions inside child class using super keyword.

Kotlin Overriding Properties

Similarly, we can also override properties and change their value inside child class. The properties should be marked open in order to override them and use the override keyword in the child class when we override the property just like we did for class functions.

package inheritance

// parent class
open class Vehicle{
    open val color: String = "Black"
    open fun printColor(){
        println("The color of vehicle is: $color")
    }
}
// child class
class Jeep: Vehicle(){
    override val color: String = "Red"
    override fun printColor(){
        println("The color of Jeep is: $color")
    }
}

fun main() {
    val jeep = Jeep()
    jeep.printColor()
}


The color of Jeep is: Red

Summary

In this tutorial we discussed about inheritance in Kotlin, how to create parent-child relationship in classes, how constructors behave during Inhertiance and method and property overriding. In the next tutorial we will discuss about Abstract classes in Kotlin.



About the author:
I'm a writer at studytonight.com.