Multiple Interfaces
In this page:
class ClassName : BaseClass(), InterfaceA, InterfaceB {
override fun method() {
super<InterfaceA>.method() // pick which default to use
}
}
Implementing Several Interfaces
A class lists all the interfaces it implements after the colon, separated by commas, and must satisfy every abstract member from each one.
Example: Implementing Several Interfaces
// Define an interface `Flyable` describing required behavior
interface Flyable {
// Define the function `fly` with no parameters and returning a String
fun fly(): String
}
// Define an interface `Swimmable` describing required behavior
interface Swimmable {
// Define the function `swim` with no parameters and returning a String
fun swim(): String
}
// Define a class `Duck`
class Duck : Flyable, Swimmable {
override fun fly(): String = "Duck is flying"
override fun swim(): String = "Duck is swimming"
}
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `duck`, set to `Duck()`
val duck = Duck()
// Print `duck.fly()` to the console, with a trailing newline
println(duck.fly())
// Print `duck.swim()` to the console, with a trailing newline
println(duck.swim())
}
Login to try C/C++/Java/PHP code in the editor
Resolving Conflicting Default Methods
If two interfaces both provide a default implementation for a method with the same name, the implementing class must override it itself to resolve the ambiguity.
Example: Resolving Conflicting Default Methods
// Define an interface `A` describing required behavior
interface A {
// Define the function `describe` with no parameters and returning a String
fun describe(): String = "From A"
}
// Define an interface `B` describing required behavior
interface B {
// Define the function `describe` with no parameters and returning a String
fun describe(): String = "From B"
}
// Define a class `C`
class C : A, B {
override fun describe(): String = super<A>.describe() + " and " + super<B>.describe()
}
// Entry point: execution of the program starts here
fun main() {
// Print `C().describe()` to the console, with a trailing newline
println(C().describe())
}
Login to try C/C++/Java/PHP code in the editor
Combining a Base Class and Interfaces
When a class both extends a base class and implements interfaces, the base class comes first in the list, followed by the interfaces, all separated by commas.
Example: Combining a Base Class and Interfaces
open class Animal(val name: String)
// Define an interface `Trainable` describing required behavior
interface Trainable {
// Define the function `train` with no parameters and returning a String
fun train(): String
}
// Define a class `Dog`
class Dog(name: String) : Animal(name), Trainable {
override fun train(): String = "$name learned to sit"
}
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `dog`, set to `Dog("Rex")`
val dog = Dog("Rex")
// Print `dog.train()` to the console, with a trailing newline
println(dog.train())
}
Login to try C/C++/Java/PHP code in the editor
Interfaces as Type Contracts
A variable can be declared with an interface type even when it holds an instance of a concrete class, letting code depend only on the shared contract rather than a specific implementation.
Example: Interfaces as Type Contracts
// Define an interface `Playable` describing required behavior
interface Playable {
// Define the function `play` with no parameters and returning a String
fun play(): String
}
// Define a class `Song`
class Song : Playable {
override fun play(): String = "Playing a song"
}
// Define a class `Video`
class Video : Playable {
override fun play(): String = "Playing a video"
}
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `items` (a `List<Playable>`), set to `listOf(Song(), Video())`
val items: List<Playable> = listOf(Song(), Video())
// Loop over `items`, binding each item to `item`
for (item in items) {
// Print `item.play()` to the console, with a trailing newline
println(item.play())
}
}
Login to try C/C++/Java/PHP code in the editor
- Assuming multiple interface implementation is the same as multiple class inheritance; Kotlin still only allows one base class but many interfaces.
- Forgetting to disambiguate when two interfaces provide the same default method name, which requires an explicit
super<InterfaceName>.method()call. - Listing interfaces in the wrong place, after a base class, without realizing order there doesn't matter for interfaces (though the class must come first if present).
- A class can implement any number of interfaces, separated by commas after the colon.
- When two implemented interfaces provide the same default method, the class must override it and can call a specific one with
super<InterfaceName>.method(). - A single base class (if any) is listed first, followed by interfaces, all separated by commas.
- Implementing multiple interfaces is how Kotlin achieves a form of multiple inheritance for behavior contracts.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: