Kotlin Inheritance

Creating classes based on other classes

๐Ÿงฌ What is Inheritance?

Inheritance in Kotlin allows you to create new classes based on existing ones. Child classes inherit properties and functions from parent classes, promoting code reuse and creating hierarchical relationships between related classes.


// Parent class (must be open to be inherited)
open class Animal(val name: String) {
    open fun makeSound() {
        println("$name makes a sound")
    }
}

// Child class inheriting from Animal
class Dog(name: String) : Animal(name) {
    override fun makeSound() {
        println("$name barks: Woof!")
    }
}
                                    

Usage:

val dog = Dog("Buddy")
dog.makeSound() // Buddy barks: Woof!

Key Inheritance Concepts

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ

Parent Class

Base class that others inherit from

open class Vehicle { }
๐Ÿ‘ถ

Child Class

Class that inherits from parent

class Car : Vehicle() { }
๐Ÿ”„

Override

Changing parent's behavior

override fun start() { }
๐Ÿ”“

Open Keyword

Allows inheritance and overriding

open fun move() { }

๐Ÿ”น Basic Inheritance

Create a parent class and inherit from it:

// Parent class - must be 'open' to allow inheritance
open class Vehicle(val brand: String, val model: String) {
    
    open fun start() {
        println("$brand $model is starting...")
    }
    
    open fun stop() {
        println("$brand $model has stopped")
    }
    
    fun displayInfo() {
        println("Vehicle: $brand $model")
    }
}

// Child class inheriting from Vehicle
class Car(brand: String, model: String, val doors: Int) : Vehicle(brand, model) {
    
    override fun start() {
        println("$brand $model car engine is starting with a roar!")
    }
    
    fun openDoors() {
        println("Opening $doors doors")
    }
}

fun main() {
    val vehicle = Vehicle("Generic", "Vehicle")
    val car = Car("Toyota", "Camry", 4)
    
    vehicle.start()
    vehicle.displayInfo()
    
    println()
    
    car.start()        // Overridden method
    car.stop()         // Inherited method
    car.displayInfo()  // Inherited method
    car.openDoors()    // Child-specific method
}

Output:

Generic Vehicle is starting...
Vehicle: Generic Vehicle

Toyota Camry car engine is starting with a roar!
Toyota Camry has stopped
Vehicle: Toyota Camry
Opening 4 doors

๐Ÿ”น Multiple Inheritance Levels

Create inheritance chains with multiple levels:

// Base class
open class Animal(val name: String) {
    open fun eat() {
        println("$name is eating")
    }
    
    open fun sleep() {
        println("$name is sleeping")
    }
}

// Intermediate class
open class Mammal(name: String, val furColor: String) : Animal(name) {
    
    open fun giveBirth() {
        println("$name is giving birth to live babies")
    }
    
    override fun sleep() {
        println("$name (mammal) is sleeping warmly with $furColor fur")
    }
}

// Final class
class Dog(name: String, furColor: String, val breed: String) : Mammal(name, furColor) {
    
    fun bark() {
        println("$name the $breed barks: Woof!")
    }
    
    override fun eat() {
        println("$name the dog is eating dog food")
    }
    
    fun wagTail() {
        println("$name is wagging tail happily")
    }
}

fun main() {
    val dog = Dog("Max", "golden", "Golden Retriever")
    
    // Methods from all levels of inheritance
    dog.eat()        // Overridden in Dog
    dog.sleep()      // Overridden in Mammal
    dog.giveBirth()  // From Mammal
    dog.bark()       // Dog-specific
    dog.wagTail()    // Dog-specific
}

Output:

Max the dog is eating dog food
Max (mammal) is sleeping warmly with golden fur
Max is giving birth to live babies
Max the Golden Retriever barks: Woof!
Max is wagging tail happily

๐Ÿ”น Super Keyword

Use 'super' to call parent class methods from child classes:

open class Employee(val name: String, val salary: Double) {
    
    open fun work() {
        println("$name is working")
    }
    
    open fun getDetails(): String {
        return "Employee: $name, Salary: $salary"
    }
}

class Manager(name: String, salary: Double, val teamSize: Int) : Employee(name, salary) {
    
    override fun work() {
        super.work()  // Call parent's work method first
        println("$name is also managing a team of $teamSize people")
    }
    
    override fun getDetails(): String {
        val baseDetails = super.getDetails()  // Get parent's details
        return "$baseDetails, Team Size: $teamSize"
    }
    
    fun conductMeeting() {
        println("$name is conducting a team meeting")
    }
}

fun main() {
    val employee = Employee("John", 50000.0)
    val manager = Manager("Sarah", 80000.0, 5)
    
    println("=== Employee ===")
    employee.work()
    println(employee.getDetails())
    
    println("\n=== Manager ===")
    manager.work()
    println(manager.getDetails())
    manager.conductMeeting()
}

Output:

=== Employee ===
John is working
Employee: John, Salary: 50000.0

=== Manager ===
Sarah is working
Sarah is also managing a team of 5 people
Employee: Sarah, Salary: 80000.0, Team Size: 5
Sarah is conducting a team meeting

๐Ÿง  Test Your Knowledge

What keyword must be used to make a class inheritable in Kotlin?