Interfaces and Inheritance
Kotlin's interfaces, and why classes are final unless marked open.
What you'll learn
- Declare and implement an interface
- Explain why Kotlin classes are final by default, and how open/override change that
- Distinguish an interface from an abstract concept a class inherits from
Explanation
A Kotlin interface declares a contract of methods (and optionally properties) a class must implement: interface Greeter { fun greet(): String }, then class EnglishGreeter : Greeter { override fun greet() = "Hello!" } -- note the : for "implements/extends" (Kotlin uses one syntax for both) and the required override keyword, which makes it explicit and searchable which methods override something.
A genuinely distinctive Kotlin design choice: classes are final by default -- you cannot subclass a regular Kotlin class unless it's explicitly marked open. This is the opposite default from Java (where classes are open unless marked final), reflecting Kotlin's philosophy that inheritance should be a deliberate design decision, not an accident of forgetting to seal a class.
To allow subclassing, mark the class open class Animal { open fun speak() = "..." }, then a subclass can extend it and override the method: class Dog : Animal() { override fun speak() = "Woof!" } -- note the parentheses after Animal (calling its constructor) and the required override keyword again.
Guided lab
Predict: Interface implementation and open-class inheritance
Read this program and predict exactly what it prints.
interface Greeter {
fun greet(): String
}
open class Animal(val name: String) {
open fun speak() = "..."
}
class Dog(name: String) : Animal(name), Greeter {
override fun speak() = "Woof!"
override fun greet() = "$name says hi"
}
fun main() {
val dog = Dog("Rex")
println(dog.speak())
println(dog.greet())
}Stuck? Get a hint.
Common mistakes
- Trying to subclass a regular Kotlin class and being surprised by a compile error -- classes are final by default; the base class must be marked `open`.
- Forgetting the `override` keyword when implementing an interface method or overriding an open method -- Kotlin requires it explicitly, unlike some languages where it's optional.
- Confusing interface implementation with class inheritance -- both use `:` in Kotlin, but a class can implement multiple interfaces while extending only one base class.
Knowledge check
Takeaway
Kotlin classes are final by default -- mark a base class `open` (and its methods `open`) deliberately to allow subclassing, and always use `override` explicitly.
Summary
Interfaces declare a contract implemented with `:` and `override`; classes are final unless marked `open`, reflecting Kotlin's deliberate-inheritance philosophy.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.