In Kotlin, interfaces define a contract that classes can implement. Kotlin supports multiple inheritance of interfaces, but not multiple inheritance of classes.
1. Defining an interface
An interface can declare:
- abstract properties
- abstract functions
- functions with default implementations
interface Drivable {
val maxSpeed: Int
fun drive()
fun stop() {
println("Stopping the vehicle")
}
}
Here:
maxSpeedmust be implemented by any class using the interface.drive()has no body, so it must be implemented.stop()has a default implementation, so overriding it is optional.
2. Implementing an interface
Use : after the class name to implement an interface.
class Car : Drivable {
override val maxSpeed: Int = 180
override fun drive() {
println("The car is driving at up to $maxSpeed km/h")
}
}
Usage:
fun main() {
val car = Car()
car.drive()
car.stop()
}
Output:
The car is driving at up to 180 km/h
Stopping the vehicle
3. Implementing multiple interfaces
A class can implement more than one interface by separating them with commas.
interface Flyable {
fun fly() {
println("Flying")
}
}
interface Swimmable {
fun swim() {
println("Swimming")
}
}
class Duck : Flyable, Swimmable
Usage:
fun main() {
val duck = Duck()
duck.fly()
duck.swim()
}
4. Handling conflicting default implementations
If two interfaces provide a function with the same signature, the implementing class must override it.
interface Printer {
fun print() {
println("Printing from Printer")
}
}
interface Scanner {
fun print() {
println("Printing from Scanner")
}
}
class AllInOneMachine : Printer, Scanner {
override fun print() {
super<Printer>.print()
super<Scanner>.print()
println("Printing from AllInOneMachine")
}
}
Usage:
fun main() {
val machine = AllInOneMachine()
machine.print()
}
Output:
Printing from Printer
Printing from Scanner
Printing from AllInOneMachine
The syntax:
super<Printer>.print()
means “call the print() implementation from the Printer interface.”
5. Interfaces with properties
Interfaces can declare properties, but they do not store state directly like classes do.
interface Identifiable {
val id: String
}
class User(
override val id: String,
val name: String
) : Identifiable
Usage:
fun main() {
val user = User("u123", "Alice")
println(user.id)
println(user.name)
}
6. Kotlin and multiple inheritance
Kotlin allows:
class Duck : Flyable, Swimmable
But Kotlin does not allow multiple class inheritance:
open class Animal
open class Machine
// Not allowed in Kotlin
class RobotDog : Animal(), Machine()
Instead, Kotlin allows:
- one superclass
- multiple interfaces
open class Animal {
fun eat() {
println("Eating")
}
}
interface Runnable {
fun run()
}
interface Trainable {
fun train()
}
class Dog : Animal(), Runnable, Trainable {
override fun run() {
println("Dog is running")
}
override fun train() {
println("Dog is training")
}
}
Key syntax
class ClassName : InterfaceName
class ClassName : InterfaceOne, InterfaceTwo
class ClassName : SuperClass(), InterfaceOne, InterfaceTwo
Summary
- Use
interfaceto define behavior. - Use
:to implement interfaces. - Use
overrideto implement interface members. - Kotlin supports multiple interface inheritance.
- Kotlin does not support inheriting from multiple classes.
- If interfaces have conflicting default methods, override the method and choose which parent implementation to call using
super<InterfaceName>.
