interface
| Since: | Kotlin 1.0(2016) |
|---|
The interface keyword in Kotlin defines a contract of methods and properties that a class must implement. Like Java, Kotlin interfaces support default implementations. A class can implement multiple interfaces, allowing flexible design without the pitfalls of multiple inheritance.
Syntax
// Define an interface
interface Drawable {
fun draw() // Abstract method (must be overridden)
fun clear() = println("Clearing") // Default implementation
val color: String // Abstract property
}
// Implement the interface
class Circle(override val color: String) : Drawable {
override fun draw() = println("Drawing a $color circle")
}
// Implement multiple interfaces
class Button : Drawable, Clickable {
override val color = "Blue"
override fun draw() = println("Drawing a button")
override fun onClick() = println("Button clicked")
}
Syntax overview
| Syntax | Description |
|---|---|
| interface Name { } | Defines an interface. |
| fun methodName() | Declares an abstract method (implementing classes must override it). |
| fun methodName() = expression | Declares a method with a default implementation (can be overridden). |
| val propertyName: Type | Declares an abstract property (implementing classes must override it). |
| ClassName : InterfaceName | Implements an interface. |
| super<InterfaceName>.method() | Explicitly calls a default implementation from a specific interface. |
Sample code
sample_interface_kotlin.kt
// Define interfaces
interface Fighter {
val name: String
fun style(): String
fun introduce() = println("I am ${name}. I use ${style()}.")
}
interface KofPlayer {
fun fight() = println("Battle start!")
fun taunt() = println("Remember me every time you look at the moon!")
}
// Implement multiple interfaces
class KofFighter(override val name: String) : Fighter, KofPlayer {
override fun style() = "Yagami-ryu Old Fighting Style"
override fun fight() {
super.fight() // Call the default implementation
println(" I'll finish you off quickly...")
}
}
class SnkFighter(override val name: String) : Fighter, KofPlayer {
override fun style() = "Kusanagi-ryu Old Fighting Style"
}
// Resolving conflicting default implementations
interface A {
fun hello() = println("Hello from A")
}
interface B {
fun hello() = println("Hello from B")
}
class C : A, B {
// When both interfaces have a default implementation, you must explicitly choose one
override fun hello() {
super<A>.hello()
super<B>.hello()
println("Additional logic in C")
}
}
fun main() {
val iori = KofFighter("Yagami Iori")
iori.introduce() // Fighter default implementation
iori.fight() // Overridden method
iori.taunt() // KofPlayer default implementation
println()
val kyo = SnkFighter("Kusanagi Kyo")
kyo.introduce()
println()
// Treat objects as their interface type
val fighters: List<Fighter> = listOf(KofFighter("Orochi Iori"), SnkFighter("Ura Kyo"))
fighters.forEach { it.introduce() }
println()
// Resolve conflicting default implementations
C().hello()
}
interface_kotlin.kt
kotlinc interface_kotlin.kt -include-runtime -d interface_kotlin.jar java -jar interface_kotlin.jar I am Yagami Iori. I use Yagami-ryu Old Fighting Style. Battle start! I'll finish you off quickly... Remember me every time you look at the moon! I am Kusanagi Kyo. I use Kusanagi-ryu Old Fighting Style. I am Orochi Iori. I use Yagami-ryu Old Fighting Style. I am Ura Kyo. I use Kusanagi-ryu Old Fighting Style. Hello from A Hello from B Additional logic in C
Common Mistakes
sample_interface_mistakes.kt
interface Fighter {
val name: String
fun greet() = println("I am ${name}")
}
interface KofPlayer {
fun greet() = println("Let the battle begin!")
}
// Implementing multiple interfaces with conflicting default methods without override
// class Kyo : Fighter, KofPlayer {
// override val name = "Kusanagi Kyo"
// }
// → greet() must be overridden — compile error
// Trying to hold state (fields) in an interface
interface HasScore {
// var score = 0 → Compile error (interfaces cannot have field initializers)
val score: Int // Declare as an abstract property instead
}
// Implementing an abstract method without the override keyword
// class Iori : Fighter {
// val name = "Yagami Iori" → Compile error (override is required)
// fun greet() = println("...") → Compile error (override is required)
// }
class Iori : Fighter, KofPlayer {
override val name = "Yagami Iori"
override fun greet() {
super<Fighter>.greet()
super<KofPlayer>.greet()
}
}
fun main() {
val iori = Iori()
iori.greet()
}
The command looks like this:
kotlinc sample_interface_mistakes.kt -include-runtime -d sample_interface_mistakes.jar java -jar sample_interface_mistakes.jar I am Yagami Iori Let the battle begin!
Notes
Kotlin interfaces support default implementations, giving them similar capabilities to Java 8 interfaces. However, interfaces cannot hold state (field values) — properties must either be computed via a getter or delegated to the implementing class.
When two interfaces share a default implementation with the same name, the implementing class must explicitly select one using super<InterfaceName>.method().
For the difference between interfaces and inheritance, see open / override. For the singleton pattern, see object / companion object.
If you find any errors or copyright issues, please contact us.