Kotlin Abstract Classes and Abstract Members

In this article, you will learn about Kotlin abstract classes, abstract methods and how to use them in our program with the help of examples.

Abstract Classes

An abstract class is a class that cannot be instantiated (we cannot create objects of an abstract class).

Syntax

We use the abstract keyword to declare an abstract class.

abstract class className {
//properties and functions
}

If we try to create objects of an abstract class, we will get a compilation error. For example,

//abstract class
abstract class Person {

    //class members
    var name: String = "Arun Kumar"

    fun show() {
        println("Name: $name ")
    }
}

fun main(args: Array<String>) {
    //creating Person instance
    //error: cannot create an instance of an abstract class
     val person = Person()

}

We can access the members of a class by creating its object or by creating an object of its subclass.

Abstract classes cannot be instantiated but we can create subclasses from it. We can create objects of subclasses to access members of the abstract class.

Abstract class  is used to define common characteristics of subclasses and the only purpose of the abstract class is to let other sub classes inherit from it.

Before we learn about it in detail, we need to understand abstract members.

Abstract Members

Abstract classes can contain properties that are not initialized called abstract properties and methods that contains no implementation (without any body) called abstract methods.

We use the same keyword abstract to create abstract member (abstract property or abstract function).

//abstract class
abstract class Vehicle {

   //abstract variable
    abstract var fuel: String //not initialized

   //abstract function
    abstract fun start() //no implementation

}

An abstract class can contain both abstract and non-abstract members as shown below:

abstract class Vehicle(val fuelType: String) {   // non-abstract Property

    abstract var fuelCapacity: Int      // abstract Property

    abstract fun start()   // abstract function

    abstract fun stop()   // abstract function

    fun park() {          // non-abstract function
        println("Vehicle is in park mode")
    }
}

Note: Abstract classes and abstract members are always open. You do not need to explicitly use open keyword.

Overriding abstract members

An abstract class cannot be instantiated; therefore we must inherit it so that we can access the members of an abstract class.

When an abstract class is inherited,

  • To create an object of subclass, we must have to override (provide implementation to a method already defined in superclass) all the abstract members of super class in our subclass.
  • However, if subclass does not implement abstract members, then the subclass must also be declared abstract (now subclass cannot be instantiated).
Example 
//abstract class 
abstract class Person(val name: String, val rollNo: Int) {   // non-abstract property
   
 // abstract property (Must be overridden by Subclasses)
    abstract var caste: String

    // abstract function (Must be implemented by Subclasses)
    abstract fun dateOfBirth(date: String)

    // non-abstract method
    fun show() {
        println("Student Name: $name")
        println("Roll No: $rollNo")
        println("Caste: $caste")
    }
}

//derived class inheriting Person class
class Student(name: String, rollNo: Int) : Person(name, rollNo) {

   //abstract property caste is initialized
    override var caste = "OBC"

   //implementation of abstract function dateOfBirth
    override fun dateOfBirth(date: String) {
        println("Date of Birth is: $date")
    }
}

fun main(args: Array<String>) {
    val student = Student("Arun Kumar", 100)
    student.show()
    student.dateOfBirth("02 July 1995")
}
Output
Student Name: Arun Kumar
Roll No: 100
Caste: OBC
Date of Birth is: 02 July 1995
Example explained
  • Person is an abstract class which contains abstract members ( caste (property) and dateOfBirth (function)) and non-abstract members ( name, rollNo (properties) and show (function)).
  • Student class is inherited from the super class Person. The subclass (Student) overriding the abstract members of the Person class.
  • Now creating an instance of subclass we cannot only access its members, but we can also access its superclass(Person) members (abstract and non-abstract).

Overriding a non-abstract open member with an abstract one

In Kotlin, we can override the non-abstract open members of the open class with the abstract keyword  in the abstract class.

Example
//open class
open class Vehicle {

   //open non-abstract members
    open fun start() {
        println("Vehicle is in start mode.")
    }

    open fun stop() {
        println("Vehicle is in stop mode.")
    }
}
//abstract class
abstract class FourWheeler : Vehicle() {
    //abstract functions
    abstract override fun start()

    abstract override fun stop()
}

//Car class inheriting abstract class FourWheeler
class Car : FourWheeler() {

   //implementation of abstract function start
    override fun start() {
        println("Car is in drive mode.")
    }

   //implementation of abstract function stop
    override fun stop() {
        println("Car is in stop mode.")
    }
}

fun main(args: Array<String>) {
    val vehicle = Vehicle()
    vehicle.start()
    val car = Car()
    car.start()
}
Output
Vehicle is in start mode.
Car is in drive mode.

Creating abstract class reference variable

We cannot create instance of abstract class but we can create reference variable of abstract class.

Example
//abstract class 
abstract class Vehicle {

    //abstract functions 
    abstract fun start()

    abstract fun stop()
}

//Car class inheriting abstract class Vehicle
class Car : Vehicle() {

   //implementation of abstract function start
    override fun start() {
        println("Car is in drive mode.")
    }

   //implementation of abstract function stop
    override fun stop() {
        println("Car is in stop mode.")
    }

   //subclass method
    fun park() {
        println("Car is in park mode.")
    }
}


fun main(args: Array<String>) {

    //error:'Vehicle' is abstract; cannot be instantiated
    //Vehicle vehicle = new Vehicle();

    // We can have references of abstract class type.
    val car: Vehicle = Car()
    car.start()
    car.stop()
    //error: using base class reference variable we can only access its own members.
    //car.park() //park is not a function of Vehicle abstract class.

}
Output
Car is in drive mode.
Car is in stop mode.

Note: Using abstract class reference variable we cannot access subclass members.

Abstract class Constructor

An abstract class can contain constructors and it is called when an instance of inherited class is created.

Example
//abstract class primary constructor with initializer block
abstract class Employee(name: String, age: Int) {

    init {
        println("My name is $name, $age years old  ")
    }
}

//subclass inheriting abstract class Employee
//subclass primary constructor with initializer block
class Manager(name: String, age: Int, salary: Int) : Employee(name, age) {

    init {
        println("I am Manager and earning $salary per month.")
        println()
    }

}

fun main(args: Array<String>) {
//creating subclass instance
    Manager("Arun", 40, 90000)
}
Output
My name is Arun, 40 years old 
I am Manager and earning 90000 per month.
Example
//abstract class
abstract class Employee {

    //abstract class secondary constructor
    constructor(name: String, age: Int) {
        println("My name is $name, $age years old  ")
    }
}

//subclass inheriting abstract class
class Manager : Employee {
    //secondary constructor calling abstract class secondary constructor
    constructor(name: String, age: Int, salary: Int) : super(name, age) {
        println("I am Manager and earning $salary per month.")
        println()
    }

}

fun main(args: Array<String>) {
//creating subclass instance
    Manager("Arun", 40, 90000)
}
Output
My name is Arun, 40 years old 
I am Manager and earning 90000 per month.

Visit Kotlin Constructor in Inheritance to learn more about Constructor behavior in Inheritance.

Points to Remember:

  • To create abstract classes and abstract members we use the abstract keyword.
  • Abstract methods have no implementation (method body) and abstract properties are not initialized.
  • A class containing abstract member (abstract property or abstract function ) must be declared as abstract.
  • An abstract class can contain abstract and non-abstract methods.
  • Abstract classes cannot be instantiated but we can create reference variable of abstract class.
  • Abstract class can have constructors.
  • The class inheriting the abstract class must either be declared abstract or implement abstract members.
  • To create an object of a class that extends abstract class we must have to implement its abstract members in our class.
  • If the class inheriting the abstract class is declared abstract, it’s not mandatory to override abstract methods but now we cannot create an instance of subclass.

 

Leave a Reply