English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In this article, you will learn about interfaces and how to implement interfaces in Kotlin with examples.
Kotlin interfaces are similar to Java 8in the interface. They can contain definitions of abstract methods as well as implementations of non-abstract methods. However, they cannot contain any state.
That is, an interface may have properties, but they must be abstract or must provide accessor implementations.
Recommended reading: Kotlin Abstract Classes
Kotlin abstract classes are similar to interfaces, but there is an important difference. The properties of an abstract class are not necessarily abstract or provided with accessor implementations.
The keyword interface is used to define interfaces in Kotlin. For example,
interface MyInterface { var test: String //Abstract properties fun foo() //Abstract method fun hello() = "Hello there" //Methods with default implementations }
Here,
Create the interface MyInterface.
The interface has an abstract property test and an abstract method foo().
The interface also has a non-abstract method hello().
This is how a class or object implements an interface:
interface MyInterface { val test: Int //Abstract properties fun foo() : String //Abstract methods (returning a string) fun hello() { //Methods with default implementations // body (optional) } } class InterfaceImp: MyInterface { override val test: Int = 25 override fun foo() = "Lol" //Other code }
Here, the InterfaceImp class implements the MyInterface interface.
This class overrides the abstract members of the interface (test property and foo() method).
interface MyInterface { val test: Int fun foo() : String fun hello() { println("Hello, mate!") } } class InterfaceImp: MyInterface { override val test: Int = 25 override fun foo() = "Lol" } fun main(args: Array<String>) { val obj = InterfaceImp() println("test = ${obj.test}") print("Call hello(): ") obj.hello() print("Call and print foo(): ") println(obj.foo()) }
When running the program, the output is:
test = 25 Call hello(): Hello, mate! Call and print foo(): Lol
As mentioned earlier, interfaces can also have properties that provide accessor implementations. For example,
interface MyInterface { //Properties with implementation val prop: Int get() = 23 } class InterfaceImp: MyInterface { //Class body } fun main(args: Array<String>) { val obj = InterfaceImp() println(obj.prop) }
When running the program, the output is:
23
Here, prop is not abstract, but it is valid in the interface because it provides an accessor implementation.
However, you cannot execute something like val prop: Int = 23 operations.
Kotlin does not allow true multiple inheritance. However, you can implement two or more interfaces in a class. For example,
interface A { fun callMe() { println("From interface A") } } interface B { fun callMeToo() { println("From interface B") } } //Implement interfaces A and B class Child: A, B fun main(args: Array<String>) { val obj = Child() obj.callMe() obj.callMeToo() }
When running the program, the output is:
From interface A From interface B
Assuming two interfaces (A and B) have non-abstract methods with the same name (assuming callMe() method). You implement these two interfaces in a class (assuming C). Now, if you call the callMe() method using an object of the C class, the compiler will throw an error. For example
interface A { fun callMe() { println("Interface A") } } interface B { fun callMe() { println("Interface B") } } class Child: A, B fun main(args: Array<String>) { val obj = Child() obj.callMe() }
This is the error thrown:
Error: (14, 1): Kotlin: Class 'C' must override public open fun callMe(): Unit defined in A because it inherits multiple interface methods of it
To solve this problem, you need to provide your own implementation. Here's how to do it:
interface A { fun callMe() { println("Interface A") } } interface B { fun callMe() { println("Interface B") } } class C: A, B { override fun callMe() { super<A>.callMe() super<B>.callMe() } } fun main(args: Array<String>) { val obj = C() obj.callMe() }
Now, when you run the program, the output will be:
Interface A Interface B
Here, an explicit implementation of the callMe() method is provided in the C class.
class C: A, B { override fun callMe() { super<A>.callMe() super<B>.callMe() } }
The statement super<A>.callMe() calls the callMe() method of class A. Similarly, super<B>.callMe() calls the callMe() method of class B.