๐ŸŽ“ A1Learner
๐Ÿ”
0 of 37 lessons completed

Kotlin Interfaces

An interface lists properties and methods that a class promises to provide. A class can implement one interface or several interfaces at once.

A default method kept and overridden

Named holds an abstract name property and a default label method. Pet keeps the default method, and ShoutPet overrides it.

interface Named {
    val name: String
    fun label(): String = "Name: $name"
}
class Pet(override val name: String) : Named
class ShoutPet(override val name: String) : Named {
    override fun label(): String = "NAME: ${name.uppercase()}"
}
fun main() {
    println(Pet("Rex").label())
    println(ShoutPet("Rex").label())
}

An abstract method with a default partner

Greeter leaves greet abstract and gives hello a default body. Casual supplies greet and keeps the default hello.

interface Greeter {
    fun greet(): String
    fun hello(): String = "Hello"
}
class Casual : Greeter {
    override fun greet(): String = "Hey there"
}
fun main() {
    val greeter = Casual()
    println(greeter.greet())
    println(greeter.hello())
}

Two defaults with the same name fail

First and Second both give hello a default body. Greeter inherits both versions and overrides neither, so the program fails to compile.

interface First {
    fun hello(): String = "from First"
}
interface Second {
    fun hello(): String = "from Second"
}
class Greeter : First, Second
fun main() {
    println(Greeter().hello())
}

An override that calls both defaults

Greeter now overrides hello and calls each interface version with a qualified super call. The two results join into one line.

interface First {
    fun hello(): String = "from First"
}
interface Second {
    fun hello(): String = "from Second"
}
class Greeter : First, Second {
    override fun hello(): String = super<First>.hello() + " and " + super<Second>.hello()
}
fun main() {
    println(Greeter().hello())
}

Example

interface Playable {
    fun play(): String
    fun describe(): String = "Ready to play"
}
class Song(val title: String) : Playable {
    override fun play(): String = "Playing $title"
}
class Game(val title: String) : Playable {
    override fun play(): String = "Starting $title"
    override fun describe(): String = "Game night pick"
}
fun main() {
    val song = Song("Blue Sky")
    println(song.play())
    println(song.describe())
    val game = Game("Chess")
    println(game.play())
    println(game.describe())
}

Key points

  • An abstract property in an interface has no value of its own.
  • A class that implements an interface supplies each abstract member.
  • A method with a body in an interface is a default method.
  • A class may keep a default method as it is or override it.
  • A class can implement several interfaces in one list after the colon.
  • A class that inherits the same default method from two interfaces must override that method.

In this example, Playable declares the abstract method play and the default method describe. Song and Game each supply play with their own wording. Song keeps the default describe, while Game overrides describe with a different line.

Note

Inside an override, super with an interface name in angle brackets calls that interface version of the method.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Kotlin Playground

Exercise

A class implements two interfaces that both give the method hello a default body, and the class overrides nothing. What happens?