An abstract class is a class that cannot be instantiated. We create abstract classes to provide a common template for other classes to extend and use.

Declaring an Abstract Class

You can declare an abstract class using the abstract keyword -

abstract class Vehicle

An abstract class may contain both abstract and non-abstract properties and functions. You need to explicitly use the abstract keyword to declare a property or function as abstract -

abstract class Vehicle(val name: String,
                       val color: String,
                       val weight: Double) {   // Concrete (Non Abstract) Properties

    // Abstract Property (Must be overridden by Subclasses)
    abstract var maxSpeed: Double

    // Abstract Methods (Must be implemented by Subclasses)
    abstract fun start()
    abstract fun stop()

    // Concrete (Non Abstract) Method
    fun displayDetails() {
        println("Name: $name, Color: $color, Weight: $weight, Max Speed: $maxSpeed")
    }
}

Any subclass that extends the abstract class must implement all of its abstract methods and properties, or the subclass should also be declared as abstract.

If you recall from the Kotlin Inheritance tutorial, you need to annotate a class as open to allow other classes to inherit from it. But, you don’t need to do that with abstract classes. Abstract classes are open for extension by default.

Similarly, abstract methods and properties are open for overriding by default.

But, If you need to override a non-abstract method or property, then you must mark it with the open modifier.

Extending from an Abstract class

Following are two concrete classes that extend the Vehicle abstract class and override its abstract methods and properties -

class Car(name: String,
          color: String,
          weight: Double,
          override var maxSpeed: Double): Vehicle(name, color, weight) {

    override fun start() {
        // Code to start a Car
        println("Car Started")
    }

    override fun stop() {
        // Code to stop a Car
        println("Car Stopped")
    }
}
class Motorcycle(name: String,
           color: String,
           weight: Double,
           override var maxSpeed: Double): Vehicle(name, color, weight) {

    override fun start() {
        // Code to Start the Motorcycle
        println("Bike Started")
    }

    override fun stop() {
        // Code to Stop the Motorcycle
        println("Bike Stopped")
    }
}

Let’s now write some code to test our abstract and concrete classes in the main method -

fun main(args: Array<String>) {

    val car = Car("Ferrari 812 Superfast", "red", 1525.0, 339.60)
    val motorCycle = Motorcycle("Ducati 1098s", "red", 173.0, 271.0)

    car.displayDetails()
    motorCycle.displayDetails()

    car.start()
    motorCycle.start()
}

Here is the output of the above main() method -

# Output
Name: Ferrari 812 Superfast, Color: red, Weight: 1525.0, Max Speed: 339.6
Name: Ducati 1098s, Color: red, Weight: 173.0, Max Speed: 271.0
Car Started
Bike Started

Conclusion

Abstract classes help you abstract out common functionality into a base class. It may contain both abstract and non-abstract properties and methods. An abstract class is useless on its own because you cannot create objects from it. But, other concrete (non-abstract) classes can extend it and build upon it to provide the desired functionality.

I hope you understood how abstract classes work in kotlin. Please ask any doubts that you might have in the comment section below.