Kotlin Inheritance Explained: Write Smarter, Reusable Code

Table of Contents

Kotlin makes object-oriented programming simple and powerful with its inheritance system. If you’re coming from Java or another OOP language, understanding Kotlin inheritance will help you write smarter, reusable code with fewer lines and more efficiency.

In this guide, we’ll break down Kotlin inheritance step by step, making it easy to grasp and apply in real-world scenarios.

What Is Kotlin Inheritance?

Inheritance is a fundamental concept in object-oriented programming (OOP). It allows a class to acquire the properties and behaviors of another class, reducing code duplication and improving maintainability.

In Kotlin, inheritance works by creating a base class (parent class) and allowing other classes (child classes) to derive from it.

By default, all Kotlin classes are final (cannot be inherited). To make a class inheritable, you must explicitly use the open keyword.

Kotlin
// Parent class
open class Animal {
    fun eat() {
        println("This animal is eating")
    }
}

// Child class inheriting from Animal
class Dog : Animal() {
    fun bark() {
        println("The dog is barking")
    }
}
fun main() {
    val myDog = Dog()
    myDog.eat() // Inherited method
    myDog.bark() // Child class method
}

Here,

  • The Animal class is open, making it inheritable.
  • The Dog class extends Animal using the : symbol.
  • The Dog class gets access to the eat() function from Animal.
  • The bark() function is specific to Dog.

Primary Constructor in Kotlin Inheritance

When a child class inherits from a parent class that has a constructor, it must initialize it. Here’s how it works:

Kotlin
open class Animal(val name: String) {
    fun eat() {
        println("$name is eating")
    }
}

class Dog(name: String) : Animal(name) {
    fun bark() {
        println("$name is barking")
    }
}
fun main() {
    val myDog = Dog("Buddy")
    myDog.eat()
    myDog.bark()
}

What’s Happening Here?

  • The Animal class has a primary constructor with a name parameter.
  • The Dog class calls the Animal constructor using : Animal(name).
  • When we create a Dog object, we pass a name that is used in both eat() and bark().

Overriding Methods in Kotlin

Kotlin allows child classes to modify or override methods from the parent class using the override keyword.

Kotlin
open class Animal {
    open fun makeSound() {
        println("Animal makes a sound")
    }
}

class Dog : Animal() {
    override fun makeSound() {
        println("Dog barks")
    }
}
fun main() {
    val myDog = Dog()
    myDog.makeSound()
}

Here,

  • The makeSound() function in Animal is open, allowing it to be overridden.
  • Dog provides its own implementation using override.
  • Now, when makeSound() is called on Dog, it prints “Dog barks” instead of “Animal makes a sound”.

If we remove open from the method but keep the class open, will it affect our code? Yes, we will get the following compile-time error:

Kotlin
'makeSound' in 'Animal' is final and cannot be overridden.

Using Superclass Methods

Sometimes, you want to modify a method but still call the original method from the parent class. You can do this using super.

Kotlin
open class Animal {
    open fun makeSound() {
        println("Animal makes a sound")
    }
}

class Dog : Animal() {
    override fun makeSound() {
        super.makeSound()
        println("Dog barks")
    }
}
fun main() {
    val myDog = Dog()
    myDog.makeSound()
}

Here, super.makeSound() calls the parent class method before executing the child class implementation.

Abstract Classes in Kotlin Inheritance

An abstract class cannot be instantiated and may contain abstract methods that must be implemented by child classes.

Kotlin
abstract class Animal {
    abstract fun makeSound()
}

class Dog : Animal() {
    override fun makeSound() {
        println("Dog barks")
    }
}
fun main() {
    val myDog = Dog()
    myDog.makeSound()
}

Why Use Abstract Classes?

  • They define a template for subclasses.
  • They ensure that all child classes implement necessary methods.

Interfaces vs. Inheritance in Kotlin

Kotlin also supports interfaces, which are similar to abstract classes but allow multiple implementations.

Kotlin
interface Animal {
    fun makeSound()
}

class Dog : Animal {
    override fun makeSound() {
        println("Dog barks")
    }
}
fun main() {
    val myDog = Dog()
    myDog.makeSound()
}

Key Differences:

  • A class can inherit only one superclass but implement multiple interfaces.
  • Interfaces cannot store state (i.e., no instance variables), while abstract classes can.

Conclusion

Kotlin inheritance is a powerful feature that helps you write smarter, reusable code. By using open classes, overriding methods, abstract classes, and interfaces, you can structure your code efficiently.

Here’s a quick recap:

  • Use open to make a class inheritable.
  • Override methods with override.
  • Use super to call the parent method.
  • Use abstract for mandatory implementations.

By mastering Kotlin inheritance, you can build scalable, maintainable, and clean applications.

Skill Up: Software & AI Updates!

Receive our latest insights and updates directly to your inbox

Related Posts

error: Content is protected !!