Open In App

Kotlin Inheritance

Last Updated : 09 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Kotlin supports inheritance, which allows you to define a new class based on an existing class. The existing class is known as the superclass or base class, and the new class is known as the subclass or derived class. The subclass inherits all the properties and functions of the superclass, and can also add new properties and functions or override the properties and functions inherited from the superclass.

Inheritance is one of the more important features in object-oriented programming. Inheritance enables code re-usability, it allows all the features from an existing class(base class) to be inherited by a new class(derived class). In addition, the derived class can also add some features of its own.

Syntax of inheritance:

open class baseClass (x:Int ) {
      ..........
}
class derivedClass(x:Int) : baseClass(x) {
     ...........
}

In Kotlin, all classes are final by default. To permit the derived class to inherit from the base class, we must use the open keyword in front of the base class.

Kotlin Inheriting property and methods from base class:
When we inherit a class then all the properties and functions are also inherited. We can use the base class variables and functions in the derived class and can also call functions using the derived class object. 

Kotlin




//base class
open class baseClass{
    val name = "GeeksforGeeks"
    fun A(){
        println("Base Class")
    }
}
//derived class
class derivedClass: baseClass() {
    fun B() {
        println(name)           //inherit name property
        println("Derived class"
    }
}
fun main(args: Array<String>) {
    val derived = derivedClass()
    derived.A()         // inheriting the  base class function
    derived.B()         // calling derived class function
}


Output: 

Base Class
GeeksforGeeks
Derived class

Explanation: 
Here, we have a base class and a derived class. We create an object while instantiating the derived class, then it is used to invoke the base class and derived class functions. The derived.A() is used to call the function A() which prints “Base Class”. The derived.B() is used to call the function B() which prints the variable name inherited from the base class and also prints “Derived class”

Use of Inheritance:

Suppose there are three types of Employee in a company a webDeveloper , an iOSDeveloper and an androidDeveloper. All of them have some shared features like name, age and also have some special kind of skills. 
First, we create three-class individually and all employees have some common and specific skills.

Here, all of them have some name and age but the development skill of all three developers are different. In each of the class, we would be copying the same code for name and age for each character. 
If we want to add a salary() feature then we need to copy the same code in all three classes. This creates a number of duplicate copies of code in our program, and it will likely lead to more complex and erratic code. 
By using inheritance, the task becomes easier. We can create a new base class Employee, which contains the common features of the 3 original classes. These three classes can then inherit common features from the base class and can add some special features of their own. We can easily add the salary feature without duplicate copies in the Employee class.

Here, for webDeveloper, we inherit all the features from the base class and its own feature website() in the class. Similarly, we can do the same for the other two classes androidDeveloper and iosDeveloper. It makes our code more understandable and extendable.

Kotlin program of inheritance –  

Kotlin




//base class
open class Employee( name: String,age: Int,salary : Int) {
    init {
        println("My name is $name, $age years old and earning $salary per month. ")
    }
}
//derived class
class webDeveloper( name: String,age: Int,salary : Int): Employee(name, age,salary) {
    fun website() {
        println("I am website developer")
        println()
    }
}
//derived class
class androidDeveloper( name: String,age: Int,salary : Int): Employee(name, age,salary) {
    fun android() {
        println("I am android app developer")
        println()
    }
}
//derived class
class iosDeveloper( name: String,age: Int,salary : Int): Employee(name, age,salary) {
    fun iosapp() {
        println("I am iOS app developer")
        println()
    }
}
//main method
fun main(args: Array<String>) {
    val wd = webDeveloper("Gennady", 25, 10000)
    wd.website()
    val ad = androidDeveloper("Gaurav", 24,12000)
    ad.android()
    val iosd = iosDeveloper("Praveen", 26,15000)
    iosd.iosapp()
}


Output: 

My name is Gennady, 25 years old and earning 10000 per month. 
I am website developer

My name is Gaurav, 24 years old and earning 12000 per month. 
I am android app developer

My name is Praveen, 26 years old and earning 15000 per month. 
I am iOS app developer

Explanation: 
Here, we have a base class Employee, prefixed with the open keyword, which contains the common properties of the derived classes. The Employee class, has a primary constructor with three variables ‘name, age and salary’. There are also three derived classes webDeveloper, androidDeveloper and iosDeveloper which also contain primary constructors and all of them having three variables.
First, we instantiate an object for the webDeveloper class, and pass the name, age and salary as parameters to the derived class. It will initialize the local variables and pass these values to the base class. Then, we call the member function website() using the object ‘wd’ which prints the string to the standard output.
Similarly, we create objects for the other two classes and invoke their respective member functions. 

Kotlin inheritance primary constructor:

If the derived class contains a primary constructor, then we need to initialize the base class constructor using the parameters of the derived class. In the below program, we have two parameters in primary constructor of base class and three parameters in derived class.

Kotlin program –  

Kotlin




//base class
open class Employee(name: String,age: Int) {
    init{
        println("Name of the Employee is $name")
        println("Age of the Employee is $age")
    }
}
// derived class
class CEO( name: String, age: Int, salary: Double): Employee(name,age) {
    init {
        println("Salary per annum is $salary crore rupees")
    }
}
fun main(args: Array<String>) {
    CEO("Sunder Pichai", 42, 450.00)
}


Output: 

Name of the Employee is Sunder Pichai
Age of the Employee is 42
Salary per annum is 450.0 crore rupees

Explanation: 
Here, we instantiate the derived class CEO and passed the parameter values name, age and salary. The derived class local variables initialize with the respective values and pass the variable name and age as parameters to the Employee class. 
The employee class prints the variable’s names and values to the standard output and transfers the control back to the derived class. Then, the derived class executes the println() statement and exits. 

Kotlin inheritance secondary constructor:

If the derived class does not contain a primary constructor, we need to call the base class secondary constructor from the secondary constructor of derived class using the super keyword. We also need to initialize the base class secondary constructor using the parameters of the derived class. 

Kotlin program: 

Kotlin




//base class
open class Employee {
    constructor(name: String,age: Int){
            println("Name of the Employee is $name")
            println("Age of the Employee is $age")
    }
}
// derived class
class CEO : Employee{
    constructor( name: String,age: Int, salary: Double): super(name,age) {
        println("Salary per annum is $salary million dollars")
    }
}
fun main(args: Array<String>) {
    CEO("Satya Nadela", 48, 250.00)
}


Output: 

Name of the Employee is Satya Nadela
Age of the Employee is 48
Salary per annum is 250.0 million dollars

Explanation: 
Here, we instantiate the class CEO and pass the parameter values to the secondary constructor. It will initialize the local variables and pass to the base class Employee using super(name,age). 

Overriding Member functions and properties:

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

Kotlin program of overriding the member function :

Kotlin




// base class
open class Animal {
    open fun run() {
        println("Animals can run")
    }
}
// derived class
class Tiger: Animal() {
    override fun run() {       // overrides the run method of base class
        println("Tiger can run very fast")
    }
}
fun main(args: Array<String>) {
    val t = Tiger()
    t.run()
}


Output: 

Tiger can run very fast

Similarly, we can override the property of the base class in the derived class.

Kotlin program of overriding the member property:

Kotlin




// base class
open class Animal {
    open var name: String = "Dog"
    open var speed = "40 km/hr"
 
}
// derived class
class Tiger: Animal() {
    override var name = "Tiger"
    override var speed = "100 km/hr"
}
fun main(args: Array<String>) {
    val t = Tiger()
    println(t.name+" can run at speed "+t.speed)
}


Output: 

Tiger can run at speed 100 km/hr

Calling the superclass implementation:

We can also call the base class member functions or properties from the derived class using the super keyword. In the below program we have called the base class property color and function displayCompany() in the derived class using the super keyword. 

Kotlin




// base class
open class Phone() {
    var color = "Rose Gold"
    fun displayCompany(name:String) {
        println("Company is: $name")
    }
}
// derived class
class iphone: Phone() {
    fun displayColor(){
       
        // calling the base class property color
        println("Color is: "+super.color)
           
        // calling the base class member function
        super.displayCompany("Apple")
    }
}
fun main(args: Array<String>) {
    val p = iphone()
    p.displayColor()
}


Output: 

Color is: Rose Gold
Company is: Apple

Advantages of using inheritance in Kotlin:

  1. Code Reusability: Inheritance allows you to reuse code from existing classes, reducing the amount of code you have to write and maintain.
  2. Improved Abstraction: By creating a class hierarchy, you can create an abstraction layer that makes your code more maintainable and less prone to bugs.
  3. Polymorphism: Inheritance allows you to create objects of different types that have the same interface, which is a fundamental aspect of object-oriented programming and enables polymorphic behavior.

Disadvantages of using inheritance in Kotlin:

  1. Complexity: Inheritance can make your code more complex, especially if you have many classes in a deep class hierarchy.
  2. Coupling: Inheritance creates a tight coupling between the superclass and the subclass, which can make it harder to change or modify the superclass without affecting the subclass.

Reference:

A popular book for learning Kotlin is “Kotlin in Action” by Dmitry Jemerov and Svetlana Isakova. This book provides a comprehensive introduction to the Kotlin programming language, including its syntax, libraries, and best practices, with many hands-on examples and exercises.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads