Kotlin Abstraction
Kotlin Abstraction is an object-oriented programming concept where a type shows what operations are available while leaving the implementation details to specific classes. In Kotlin, abstraction is commonly written with interfaces and abstract classes. Both help you design code around common behavior instead of repeating the same structure in many unrelated classes.
Use abstraction when you know what a class should be able to do, but the exact way of doing it can vary. For example, every vehicle can run, but a car, boat, and airplane run in different mediums and with different mechanisms. A common abstraction can define the expected behavior, and each concrete class can provide its own implementation.
Abstraction in Kotlin could be achieved by following ways :
Kotlin abstraction with interfaces for behavior contracts
Kotlin Interfaces have similar structure as that of a Kotlin Class, but can contain abstract methods and abstract variables. Which means, the variables of interfaces are not initialized and methods may or may not have implementations. An Interface in Kotlin enforces definite implementations of methods/behaviors/routines in classes that implements the interface.
Following is an example of Kotlin Interface.
interface Vehicle {
var name:String
fun howItRuns()
}
In this interface, name and howItRuns() are abstract members because they do not provide stored state or a method body. Any class that implements Vehicle must provide these members.
The following example shows two classes implementing the same interface in different ways.
interface Transport {
val name: String
fun move()
}
class Car : Transport {
override val name: String = "Car"
override fun move() {
println("$name moves on roads")
}
}
class Boat : Transport {
override val name: String = "Boat"
override fun move() {
println("$name moves on water")
}
}
fun main() {
val vehicles: List<Transport> = listOf(Car(), Boat())
for (vehicle in vehicles) {
vehicle.move()
}
}
Output:
Car moves on roads
Boat moves on water
The calling code works with the abstract type Transport. It does not need to know whether the object is a Car or a Boat. This is the practical value of abstraction: the common contract stays stable while each implementation can be different.
Kotlin abstraction with abstract classes and shared state
An abstract class contains abstract or non-abstract : variables and functions. Abstract Class cannot be initiated but could be extended as a Super Class.
Following is an example of Kotlin Abstract Class.
example.kt
abstract class Vehicle {
// initialized variable
var name : String = "Not Specified"
// abstract variable
abstract var medium : String
// function with body
fun runsWhere() {
println("The vehicle, $name, runs on $medium")
}
// abstract function
abstract fun howItRuns()
}
In Kotlin, an abstract class can contain implemented functions, abstract functions, initialized properties, constructors, and shared logic. A subclass extends the abstract class and provides implementations for abstract members using the override keyword.
The following complete example extends the abstract Vehicle class.
abstract class Machine(val model: String) {
abstract val powerSource: String
fun showModel() {
println("Model: $model")
}
abstract fun start()
}
class ElectricCar(model: String) : Machine(model) {
override val powerSource: String = "Battery"
override fun start() {
println("$model starts using $powerSource")
}
}
fun main() {
val car = ElectricCar("City EV")
car.showModel()
car.start()
}
Output:
Model: City EV
City EV starts using Battery
Here, Machine defines common behavior through showModel() and leaves powerSource and start() to subclasses. This is useful when all subclasses share some implementation, but still need to define part of their own behavior.
Abstract function in Kotlin
An abstract function in Kotlin is a function declared without a body inside an abstract class or interface. A concrete subclass must implement it unless the subclass is also abstract.
abstract class Report {
abstract fun generate()
}
The generate() function declares what the report must do, but not how it does it. Each subclass decides the implementation.
abstract class Report {
abstract fun generate()
}
class SalesReport : Report() {
override fun generate() {
println("Generating sales report")
}
}
fun main() {
val report: Report = SalesReport()
report.generate()
}
Output:
Generating sales report
Kotlin abstract classes vs interfaces
Following are some of the differences between Abstract Classes and Interfaces.
| Interfaces | Abstract Classes |
| Cannot have initialized variables. | Can have initialized variables. |
| A single class can implement multiple interfaces. | For a class, only one abstract class could be a super class. |
| interface keyword is used to define an interface. | abstract keyword is used to define an abstract class. |
A practical way to decide between them is this: use an interface when you want to describe a capability, and use an abstract class when you need a common base with shared state or shared implementation.
| Requirement | Better choice | Reason |
|---|---|---|
| Several unrelated classes must expose the same behavior. | Interface | A class can implement more than one interface. |
| Subclasses need common properties, constructors, or reusable methods. | Abstract class | An abstract class can hold shared state and implementation. |
| You only need to define method names and expected behavior. | Interface | It keeps the abstraction lightweight. |
| You want a partially implemented parent type. | Abstract class | It can mix implemented and abstract members. |
Kotlin abstract class and sealed class difference
An abstract class is mainly used to define a common base that subclasses must complete. A sealed class is used when the possible subclasses are restricted and known in the same hierarchy. Both can be abstract in behavior, but they solve different design problems.
Use an abstract class when new subclasses may be added normally. Use a sealed class when you want the compiler to know the limited set of possible types, such as success and error results.
sealed class NetworkResult
class Success(val data: String) : NetworkResult()
class Failure(val message: String) : NetworkResult()
fun printResult(result: NetworkResult) {
when (result) {
is Success -> println(result.data)
is Failure -> println(result.message)
}
}
In the example above, NetworkResult is sealed because the program is expected to handle a fixed set of result types. For a broad inheritance hierarchy such as vehicles, reports, or services, an abstract class is often simpler.
Common mistakes while using abstraction in Kotlin
- Trying to create an object of an abstract class: an abstract class cannot be instantiated directly.
- Forgetting override: Kotlin requires
overridewhen implementing abstract members. - Putting stored state in an interface: interfaces can declare properties, but they do not store backing fields like normal class properties.
- Using an abstract class when an interface is enough: if there is no shared state or common implementation, an interface may be clearer.
- Making every parent class abstract: abstraction is useful only when subclasses are expected to provide meaningful differences.
Kotlin abstraction FAQ
What is abstraction in Kotlin?
Abstraction in Kotlin means defining the required behavior of a type while hiding or delaying the implementation details. Interfaces and abstract classes are the two common ways to write abstraction in Kotlin.
What is an abstract function in Kotlin?
An abstract function is a function declared without a body. It must be implemented by a concrete subclass. Abstract functions can appear in abstract classes and interfaces.
Can a Kotlin abstract class have normal functions?
Yes. A Kotlin abstract class can have normal functions with bodies, abstract functions without bodies, initialized properties, constructors, and shared logic.
When should I use interface instead of abstract class in Kotlin?
Use an interface when you only want to define a behavior contract or when a class needs to implement multiple capabilities. Use an abstract class when subclasses need common state, constructors, or reusable implementation.
What is the difference between abstract and sealed classes in Kotlin?
An abstract class defines incomplete behavior that subclasses must complete. A sealed class restricts the set of possible subclasses and is useful when all possible cases should be handled, often with a when expression.
Editorial QA checklist for Kotlin abstraction tutorial
- Confirms that Kotlin abstraction is explained with both interfaces and abstract classes.
- Shows at least one runnable Kotlin example where different classes implement the same abstraction.
- Explains the role of
abstractandoverridein Kotlin code. - Clarifies when to choose an interface, an abstract class, or a sealed class.
- Uses output blocks only for program results and Kotlin language blocks only for Kotlin code.
Conclusion
In this Kotlin Tutorial, we have seen in brief the ways of implementing Abstraction in Kotlin. In our following two tutorials, we shall see Kotlin Interfaces and Kotlin Abstract Classes in detail.
TutorialKart.com