In this article, we will learn about one of the most important features of the object-oriented programming language.

Inheritance

Inheritance means a class can inherit properties and behavior from another class. The class that inherits the properties and behaviors is called derived class or subclass or child class and the class whose properties and behaviors are inherited is called a base class or superclass or parent class.

Let’s say you have classes like Car, Bus, Truck, etc. All of these classes have some properties (Data members) and some behavior (member functions) as shown in the diagram below. 

Fig. 1: Different classes and their members

You might have noticed that a lot of their properties and functions are similar. So why not create a generalized class called Vehicle with all the common stuff on it. 

Fig. 2: Inheritance

The classes like Car, Bus, and Truck can then inherit all common features from the Vehicle class. Let’s see how we can extend a class.

open class Vehicle(name: String, modelNumber: String, color: String) { /* */ }

The classes are by default not extendable so we must mark the class as open if we want to inherit from it. The subclasses can extend the open class using the following syntax.

class Car(name: String, modelNumber: String, color: String) : Vehicle(name, modelNumber, color) 

We can define inheritance by using a colon followed by the parent class name. If the derived class has a primary constructor, the base class can (and must) be initialized right there, using the parameters of the primary constructor.

If the derived class has no primary constructor, then each secondary constructor has to initialize the base type using the super keyword or to delegate to another constructor which does that.

open class Vehicle(name: String, modelNumber: String, color: String) { /* */ }

class Car : Vehicle {
    constructor(name: String, modelNumber: String, color: String) : super(name, modelNumber, color)
}

Now that we know the rules let’s convert the above code into executable code.


open class Vehicle(name: String, modelNumber: String, color: String) {
    init {
        println("We are starting your vehicle")
    }

    fun drive() {
        println("Let's drive a vehicle")
    }

    fun park() {}
    fun wash() {}
}

class Car (name: String, modelNumber: String, color: String) : Vehicle(name, modelNumber, color) {
    fun visitPlaces() {
        println("Let's visit places")
    }
}

class Bus (name: String, modelNumber: String, color: String) : Vehicle(name, modelNumber, color) {
    fun boardPassenger() {
        println("Board 20 passengers in the bus")
    }
}

class Truck (name: String, modelNumber: String, color: String) : Vehicle(name, modelNumber, color) {
    fun loadPackages() {
        println("Load 20 packages in the truck")
    }
}

fun main(args: Array<String>) {
    val car = Car("BMW", "S3", "Red")
    car.drive()
    car.visitPlaces()

    val bus = Bus("Volvo", "V1", "Blue")
    bus.boardPassenger()

    val truck = Truck("Mahendra", "T6", "White")
    truck.loadPackages()
}

//   Output
//   We are starting your vehicle
//   Let's drive a vehicle
//   Let's visit places
//   We are starting your vehicle
//   Board 20 passengers in the bus
//   We are starting your vehicle
//   Load 20 packages in the truck

Override

Kotlin allows us to rewrite the member properties or function of the base class in the derived class. This technique is known as overriding. The method or properties that we want to override should be marked open in the base class and override in the subclass. Let’s see an example of overridden methods and properties.

open class Vehicle(name: String, modelNumber: String, color: String) {
    init {
        println("We are starting your vehicle")
    }

    open var numberOfSeat = 0

    open fun drive() {
        println("Let's drive a vehicle")
    }

    fun park() {
        println("Let's park the vehicle")
    }
}

class Car(val name: String, val modelNumber: String, val color: String) : Vehicle(name, modelNumber, color) {
    override var numberOfSeat = 4

    override fun drive() {
        println("Let's drive the $name $modelNumber car of the $color color")
    }

    fun visitPlaces() {
        println("Let's visit places")
    }
}

fun main(args: Array<String>) {
    val car = Car("BMW", "S3", "Red")
    car.drive()
    car.visitPlaces()
    car.park()

    val vehicle = Vehicle("BMW", "S3", "Red")
    vehicle.drive()
}

// Output
//    We are starting your vehicle
//    Let's drive the BMW S3 car of the Red color
//    Let's visit places
//    Let's park the vehicle
//    We are starting your vehicle
//    Let's drive a vehicle

As you can see that the derived class can invoke the base class properties or member function as its own and also alter them as per the need.

The reason behind the popularity of Inheritance is that it makes the code reusable and helps to reduce redundant code by sharing the code among the subclasses. We get the flexibility to extend the base class and override the method based on our business logic. Click on the next button to continue reading.

Category
Tags

No responses yet

Leave a Reply

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