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
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
interface Greetable {
val name: String
fun style(): String
fun introduce() = println("Name: ${name}. Type: ${style()}.")
}
interface Actionable {
fun execute() = println("Processing started!")
fun notifyDone() = println("Sending completion notice")
}
// Implement multiple interfaces
class StandardItem(override val name: String) : Greetable, Actionable {
override fun style() = "standard"
override fun execute() {
super.execute() // Call the default implementation
println(" Running additional processing")
}
}
class AdvancedItem(override val name: String) : Greetable, Actionable {
override fun style() = "advanced"
}
// 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 item1 = StandardItem("item_1")
item1.introduce() // Greetable default implementation
item1.execute() // Overridden method
item1.notifyDone() // Actionable default implementation
println()
val item2 = AdvancedItem("item_2")
item2.introduce()
println()
// Treat objects as their interface type
val items: List<Greetable> = listOf(StandardItem("item_3"), AdvancedItem("item_4"))
items.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 Name: item_1. Type: standard. Processing started! Running additional processing Sending completion notice Name: item_2. Type: advanced. Name: item_3. Type: standard. Name: item_4. Type: advanced. Hello from A Hello from B Additional logic in C
Common Mistakes
sample_interface_mistakes.kt
interface Greetable {
val name: String
fun greet() = println("Name: ${name}")
}
interface Actionable {
fun greet() = println("Start processing")
}
// Implementing multiple interfaces with conflicting default methods without override
// class ItemImpl : Greetable, Actionable {
// override val name = "item_1"
// }
// → 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 ItemImpl : Greetable {
// val name = "item_1" → Compile error (override is required)
// fun greet() = println("...") → Compile error (override is required)
// }
class ItemImpl : Greetable, Actionable {
override val name = "item_1"
override fun greet() {
super<Greetable>.greet()
super<Actionable>.greet()
}
}
fun main() {
val item = ItemImpl()
item.greet()
}
The command looks like this:
kotlinc sample_interface_mistakes.kt -include-runtime -d sample_interface_mistakes.jar java -jar sample_interface_mistakes.jar Name: item_1 Start processing
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.