You are currently viewing Kotlin Inheritance

Kotlin Inheritance

Inheritance

Inheritance is a fundamental object-oriented programming (OOP) concept that allows a class (subclass or derived class) to inherit all the properties and behaviors of another class (superclass or base class).

classes are final by default, meaning they cannot be subclassed. To allow a class to be subclassed, use the open keyword.

Syntax for Inheriting: To inherit from a class, use the colon : followed by the name of the superclass.

class Subclass : Superclass() {
    // class definition
}

Base Class (Superclass): The class that is being inherited is called the superclass or base class.


open class Animal {
    // class definition
}

Derived Class (Subclass): The class that inherits from another class is called the subclass or derived class.

class Dog : Animal() {
    // class definition
}

Example of Inheriting property and methods from base class:

// Base class
open class Animal(val name: String) {
    // Property and method of the base class
    fun makeSound() {
        println("$name makes a sound")
    }
}

// Derived class inheriting from the base class
class Dog(name: String, val breed: String) : Animal(name) {
    // Additional property and method of the derived class
    fun bark() {
        println("$name barks loudly")
    }
}

fun main() {
    // Creating an instance of the derived class
    val myDog = Dog("Buddy", "Labrador")

    // Accessing properties and methods from the base class
    println("Name: ${myDog.name}")
    myDog.makeSound()

    // Accessing properties and methods from the derived class
    println("Breed: ${myDog.breed}")
    myDog.bark()
}

Explanation

Dog is a derived class that inherits from Animal using : Animal(name). Both base class (Animal) and derived class (Dog) properties and methods are accessed by Dog instance.

The : Animal(name) syntax in the derived class declaration ensures that the base class constructor is called when creating an instance of the derived class.

When you run this program, you should see the following output:

Name: Buddy
Buddy makes a sound
Breed: Labrador
Buddy barks loudly

Overriding Member functions and properties:

If Base class and derived class contains function and properties with same name, then we can override the member function of Base class in derived class using override keyword. we also need to mark the function and properties of the base class with open keyword

// Base class
open class Vehicle {
    open fun start() {
        println("Vehicle is starting")
    }

    open val fuelType: String = "Petrol"
}

// Derived class
class ElectricCar : Vehicle() {
    override fun start() {
        println("Electric car is starting")
    }

    override val fuelType: String
        get() = "Electricity"
}

The Vehicle class is a base class with a method start and a property fuelType. The ElectricCar class is a derived class that inherits from Vehicle and overrides the start method and the fuelType property.

fun main() {
    // Creating instances of base and derived classes
    val genericVehicle: Vehicle = Vehicle()
    val electricCar: Vehicle = ElectricCar()

    // Calling overridden methods
    genericVehicle.start()   // Output: Vehicle is starting
    electricCar.start()      // Output: Electric car is starting

    // Accessing overridden properties
    println("Generic Vehicle Fuel Type: ${genericVehicle.fuelType}") // Output: Generic Vehicle Fuel Type: Petrol
    println("Electric Car Fuel Type: ${electricCar.fuelType}")       // Output: Electric Car Fuel Type: Electricity
}

Explanation:

When genericVehicle.start() is called, the compiler looks at the type of genericVehicle at compile-time, which is Vehicle. It then knows to call the start method defined in the Vehicle class.

when electricCar.start() is called, the compiler looks at the type of electricCar at compile-time, which is still Vehicle (due to the declared type). However, at runtime, the actual type of the object is ElectricCar. Therefore, the overridden start method in the ElectricCar class is called. (Output: Electric car is starting)

Advantage of using Inheritance in kotlin:

  1. Code Reusability: Inheritance allows you to reuse code from an existing class. Instead of writing the same code multiple times for different classes, you can create a base class with common attributes and methods. Subclasses can then inherit these features, reducing redundancy and making the code more maintainable.
  2. Polymorphism: Inheritance supports polymorphism, allowing objects of a derived class to be used wherever objects of the base class are expected.
  3. Base Class Abstraction: A base class provides an abstraction of common properties and behaviors, serving as a blueprint for derived classes to follow.
  4. Extensibility: it is easy to add new features or change existing ones without messing up the original code. It’s like building on top of what you already have.
  5. Maintenance and Updates: It is easy to change something, it’s easier to find and update. If you fix or improve the basic template (base class), all the similar things (subclasses) automatically get the update.

Disadvantage of using Inheritance in kotlin:

  1. Increased Code Complexity: If you have lots of classes arranged in a deep hierarchy, using inheritance can make code more complicated.
  2. Tight Connection Between Classes: Inheritance creates a strong link between a main class (superclass) and its related classes (subclasses). This close connection can make it hard to make changes to the main class without affecting the others.
  3. Issues with Changing and Adding Features: When you make changes to the main class, it can cause problems throughout the whole hierarchy of classes. This can be a headache when you want to add new features or modify existing ones.