Kotlin Abstract Class

Kotlin Abstract Class is one of the way to implement abstraction in Kotlin. An abstract class can contain abstract members, which have no implementation, and regular members, which already have implementation. A concrete subclass must implement the abstract properties and abstract functions inherited from the abstract class.

Following is a sample of how a Kotlin Abstract Class looks.

</>
Copy
abstract class Vehicle {
    // regular variable
    var name : String = "Not Specified"
    // abstract variable
    abstract var medium : String
    // regular function
    fun runsWhere() {
        println("The vehicle, $name, runs on $medium")
    }
    // abstract function
    abstract fun howItRuns()
}

*regular meaning the variable/function is initialized/defined.

Kotlin Abstract Class Syntax

Use the abstract keyword before class to declare an abstract class. Abstract functions and abstract properties are declared inside the class without an implementation or initializer.

</>
Copy
abstract class ClassName {
    abstract val propertyName: Type

    abstract fun functionName()

    fun regularFunction() {
        // common implementation
    }
}

An abstract class does not need the open keyword. It is meant to be inherited. However, regular non-abstract members inside an abstract class are final by default unless they are marked with open.

About Kotlin Abstract Class

Let us consider following simple example that demonstrates the usage of Abstract class, and then draw the list of points about Kotlin Abstract Class.

example.kt

</>
Copy
/**
 * Abstract Class
 */
abstract class Vehicle {
    // regular variable
    var name : String = "Not Specified"
    // abstract variable
    abstract var medium : String
    // regular function
    fun runsWhere() {
        println("The vehicle, $name, runs on $medium")
    }
    // abstract function
    abstract fun howItRuns()
}

/**
 * inheriting abstract class
 */
class Aeroplane : Vehicle() {
    // override abstract variables and functions of the
    // abstract class that is inherited
    override var medium: String = "air"

    override fun howItRuns() {
        println("Aeroplane fly based on buoyancy force.")
    }

}

fun main(args: Array<String>) {
    var vehicle1 = Aeroplane()
    vehicle1.howItRuns()
}

Let us break down the above example, and analyze the code.

1. abstract keyword is used to declare an abstract class.

</>
Copy
abstract class Vehicle { }

2. Abstract classes cannot be instantiated.

</>
Copy
fun main(args: Array<String>) {
    var vehicle:Vehicle = Vehicle()
}
Error:(2, 27) Kotlin: Cannot create an instance of an abstract class

3. Abstract classes can be inherited.

</>
Copy
class Aeroplane : Vehicle() { }

4. Variables and functions of an abstract class could be declared either as abstract or not.

</>
Copy
class Aeroplane : Vehicle() { }

5. Abstract variables are not initialized. Abstract methods does not have an implementation.

</>
Copy
    // abstract variable
    abstract var medium : String

    // abstract function
    abstract fun howItRuns()

6. In the inherited class, unless it is also an abstract class, variables and functions, not declared as abstract are not mandatory to override. Abstract variables and abstract functions must be overridden.

</>
Copy
class Aeroplane : Vehicle() {
    // override abstract variables and functions of the
    // abstract class that is inherited
    override var medium: String = "air"

    override fun howItRuns() {
        println("Aeroplane fly based on buoyancy force.")
    }
}

7. To override non-abstract methods, they must be declared open. You may refer Kotlin Inheritance for a detailed example.

Kotlin Abstract Properties and Functions in a Subclass

A non-abstract subclass must provide values for all abstract properties and bodies for all abstract functions. The subclass uses the override keyword for each abstract member it implements.

</>
Copy
fun main() {
    val car = Car("Swift")
    car.runsWhere()
    car.howItRuns()
}

abstract class Transport(val name: String) {
    abstract val medium: String

    fun runsWhere() {
        println("$name runs on $medium")
    }

    abstract fun howItRuns()
}

class Car(name: String) : Transport(name) {
    override val medium: String = "road"

    override fun howItRuns() {
        println("$name runs using an engine and wheels.")
    }
}

Output

Swift runs on road
Swift runs using an engine and wheels.

In this example, Transport defines the common structure. The Car class supplies the value for medium and the implementation for howItRuns(). The regular function runsWhere() is reused by the subclass without being overridden.

Kotlin Abstract Class with Constructor

An abstract class can have a primary constructor. The constructor is used by subclasses when they initialize the abstract class part of the object.

</>
Copy
fun main() {
    val account = SavingsAccount("A1001", 25000.0)
    account.printAccountType()
    println(account.calculateInterest())
}

abstract class BankAccount(val accountNumber: String, val balance: Double) {
    fun printAccountType() {
        println("Account number: $accountNumber")
    }

    abstract fun calculateInterest(): Double
}

class SavingsAccount(accountNumber: String, balance: Double) : BankAccount(accountNumber, balance) {
    override fun calculateInterest(): Double {
        return balance * 0.04
    }
}

Output

Account number: A1001
1000.0

The subclass SavingsAccount passes constructor values to BankAccount. The abstract class stores common data and provides a regular function, while the subclass defines the account-specific interest calculation.

Overriding Regular Members in Kotlin Abstract Classes

Regular functions in an abstract class are not automatically open. If a subclass must override a regular function, mark that function with open in the abstract class.

</>
Copy
abstract class Report {
    open fun title() {
        println("General Report")
    }

    abstract fun printBody()
}

class SalesReport : Report() {
    override fun title() {
        println("Sales Report")
    }

    override fun printBody() {
        println("Sales data goes here")
    }
}

If title() is not marked as open, the subclass cannot override it. Abstract functions do not need open because they are meant to be implemented by subclasses.

Kotlin Abstract Class vs Interface

Abstract classes and interfaces both help define common behavior, but they are used in different situations.

FeatureAbstract ClassInterface
InheritanceA class can inherit from one abstract class.A class can implement multiple interfaces.
StateCan store state using constructor properties and regular properties.Can declare properties, but it is mainly used as a contract.
ConstructorCan have constructors.Cannot have constructors.
Best useUse when related classes share common state and base behavior.Use when different classes should follow the same capability or contract.

For example, Vehicle can be an abstract class when every vehicle has common state such as name or speed. An interface such as Drivable can be used when unrelated classes need to provide a driving behavior.

Common Kotlin Abstract Class Mistakes

  • Trying to create an object of an abstract class: Create an object of a concrete subclass instead.
  • Adding a body to an abstract function: An abstract function must not have an implementation.
  • Forgetting override in the subclass: Abstract members must be implemented with the override keyword.
  • Leaving abstract members unimplemented in a concrete class: Either implement all abstract members or make the subclass abstract.
  • Trying to override a regular function that is not open: Add open to the regular function in the abstract class if overriding is required.

Kotlin Abstract Class FAQs

Can we create an object of an abstract class in Kotlin?

No. An abstract class cannot be instantiated directly. You must create an object of a concrete subclass that implements all abstract members.

Does a Kotlin abstract class need the open keyword?

No. An abstract class is inheritable by design, so the class itself does not need open. Regular functions inside it still need open if they should be overridden.

Can an abstract class have normal functions in Kotlin?

Yes. A Kotlin abstract class can have normal functions with complete implementation. Subclasses can use those functions directly.

Can an abstract class have a constructor in Kotlin?

Yes. An abstract class can have a primary constructor and secondary constructors. Subclasses call those constructors while extending the abstract class.

When should I use an abstract class instead of an interface in Kotlin?

Use an abstract class when related subclasses need shared state, constructor values, or common base implementation. Use an interface when you mainly need to define a capability that different classes can implement.

Editorial QA Checklist for Kotlin Abstract Class Tutorial

  • Confirm that every abstract member in examples has no initializer or function body.
  • Check that every concrete subclass implements all inherited abstract properties and functions.
  • Verify that regular members are described as final by default unless marked open.
  • Make sure output blocks use the output class and syntax-only blocks use language-kotlin syntax.
  • Review examples to ensure abstract class and interface usage are not described as identical.

Conclusion

In this Kotlin Tutorial, we learned about Abstract Classes in Kotlin. An abstract class is useful when a group of related subclasses should share common properties or functions while still being forced to implement specific behavior. We also saw how abstract properties, abstract functions, constructors, and regular open members work inside Kotlin abstract classes.