English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Kotlin Interfaces (Interface)

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.

How to define an interface?

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().

How to implement an interface?

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).

Example: How does the interface work?

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.

Implementing two or more interfaces in a class

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

Resolving Overriding Conflicts (Multiple Interfaces)

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.