← Back to Kotlin Course | Chapter 7: Inheritance & Interfaces | Lesson 5 of 7

Multiple Interfaces

Multiple interfaces let one class agree to several separate checklists of abilities all at once, something a single base class can't do.
Syntax
kotlin
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

markup
// 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())
}

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

markup
// 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())
}

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

markup
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())
}

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

markup
// 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())
    }
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assuming multiple interface implementation is the same as multiple class inheritance; Kotlin still only allows one base class but many interfaces.
  2. Forgetting to disambiguate when two interfaces provide the same default method name, which requires an explicit super<InterfaceName>.method() call.
  3. 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).
Chapter Summary
  • 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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.