Abstract Class vs Interface in Kotlin: Key Differences and Usage
abstract class can hold state and provide constructor logic, while an interface cannot hold state but can declare abstract methods and default implementations. Use abstract classes when you need shared code and state, and interfaces for defining contracts that multiple classes can implement.Quick Comparison
Here is a quick side-by-side comparison of abstract classes and interfaces in Kotlin.
| Feature | Abstract Class | Interface |
|---|---|---|
| State (fields) | Can have state (properties with backing fields) | Cannot have state (properties are abstract or have default getters) |
| Constructors | Can have constructors | Cannot have constructors |
| Multiple inheritance | Supports single inheritance only | Supports multiple inheritance (a class can implement many interfaces) |
| Method implementation | Can have both abstract and concrete methods | Can have abstract methods and default implementations |
| Use case | Use for shared base functionality and state | Use for defining contracts and capabilities |
| Access modifiers | Can have visibility modifiers (private, protected, etc.) | Members can have visibility modifiers (default is public) |
Key Differences
An abstract class in Kotlin is like a blueprint for other classes that can hold state and provide constructor logic. It can have properties with backing fields, meaning it can store data. It also supports visibility modifiers like private or protected, allowing you to control access to its members. However, a class can only inherit from one abstract class, limiting multiple inheritance.
On the other hand, an interface defines a contract that classes can implement. Interfaces cannot hold state but can declare properties without backing fields or provide default implementations for methods. They do not have constructors, and members can have visibility modifiers (default is public). Kotlin allows a class to implement multiple interfaces, enabling flexible multiple inheritance of behavior.
In summary, use abstract classes when you want to share code and state among related classes, and use interfaces when you want to define capabilities or contracts that can be applied across unrelated classes.
Code Comparison
abstract class Animal(val name: String) { abstract fun sound(): String fun describe() = "This is $name" } class Dog(name: String) : Animal(name) { override fun sound() = "Woof" } fun main() { val dog = Dog("Buddy") println(dog.describe()) println(dog.sound()) }
Interface Equivalent
interface Animal {
val name: String
fun sound(): String
fun describe() = "This is $name"
}
class Dog(override val name: String) : Animal {
override fun sound() = "Woof"
}
fun main() {
val dog = Dog("Buddy")
println(dog.describe())
println(dog.sound())
}When to Use Which
Choose an abstract class when:
- You need to share common code and state (properties with backing fields) among related classes.
- You want to provide constructor logic or control member visibility.
- Your design fits a clear class hierarchy with single inheritance.
Choose an interface when:
- You want to define a contract or capability that can be added to any class, unrelated or related.
- You need multiple inheritance of behavior since a class can implement many interfaces.
- You do not need to store state or provide constructor logic.