In Kotlin, abstract classes (abstract class) and interfaces (interface) are used to declare abstract logic, but there are significant differences between them:
abstract class Animal(val name: String) { abstract fun makeSound() fun info() = println("I am $name") } interface Movable { fun move() } class Cat(name: String) : Animal(name), Movable { override fun makeSound() = println("Meow") override fun move() = println("Cat moves") }
Can an interface in Kotlin contain state (backing field)?
Most people answer that properties can be declared in the interface, but they still do not have a backing field — only getters/setters without storing values. Even if you write get() = ... — the value will be computed each time.
Example:
interface MyInterface { val value: Int get() = 42 // no value storage, computed on the fly }
Story
In a large project, a senior developer tried to store state in an interface (e.g., a counter), expecting the property var count: Int to have a backing field. As a result, all implementing classes had to handle value storage differently, leading to unstable logic (data was lost if the setter was forgotten).
Story
One of the developers used an abstract class where multiple implementations of different behavior strategies were required (strategy pattern). This led to a problem: only one base class per hierarchy, but composition was needed for different aspects of behavior. The architecture had to be changed to interfaces.
Story
The team attempted to inherit from two abstract classes at once (one with logic, the other with common utilities), which is not possible in Kotlin. The problem emerged during the application expansion phase. This resulted in significant technical debt, as the classes had to be urgently reorganized.