Kotlin Interfaces Tutorial

In this section, we will learn what the Interfaces are and how they work in Kotlin.

What is Interface in Kotlin?

Before we get into the Kotlin Interface, you should know that an interface is something that you see and can interact with when working with a tool. Basically, an interface is your way of accessing and using the functionalities of a tool.

For example, the interface of a car when sitting on the driver seat includes the steering wheel, pedals, gear and a set of buttons that controls the light, temperature and other accessories in the car.

Now, in the world of programming, when creating an object, the things you’re allowed to call and work with in that object are the interface of that object.

For example, the properties and functions of an object that we can call are then part of the interface that the object provides.

Now if we want to set one or more classes (hence their future objects) to all have the same interface, no-matter what data type they have, we can use the Kotlin interface!

An interface in Kotlin is nothing but a place where we can define properties and functions just like classes. But the main difference is that at an interface we can put abstract properties and functions as well as normal functions and properties.

You might be asking then what’s the difference between an abstract class and an interface then? It seems both of them are capable of doing the same thing.

Well, the main difference between these two are:

  • A concrete class can only inherit from one abstract class. But even in that case, first there must be the is-a relation between the abstract and concrete classes so that we could make a class inherit the other.
  • But using the interfaces, we can have more than one interface to be implemented by a class. Also note that there’s no need to be a relation between an interface and the classes that implemented it!
  • For example, if there’s an interface with a function named steer(), this interface could be implemented using a class called Car and another class called Bicycle and each of these classes can define their own version for the body of the function.

Alright, let’s see how we can create an interface in Kotlin now.

How to create an Interface in Kotlin?

This is the syntax of creating an interface in Kotlin:

interface InterfaceName{

// body of the interface…

}

interface: in order to create an interface in Kotlin, we start with the keyword interface.

After that comes the name of the interface (which should follow the convention that we apply to the names of classes) and after that, we put the members of an interface within a pair of braces {} that comes after the interface name.

As you’ll soon see, the members of an interface could be either concrete properties and functions or abstract functions and properties.

Example: declaring an interface in Kotlin

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

Here we have an interface called Animal and it has 3 members.

The age property and sound() function are abstract because the property is not initialized and the function doesn’t have a body. So that means the interface is implemented by a class, we must provide a value for the property and also set a body for the function.

Note that we don’t need to add the abstract keyword in front of abstract members of an interface.

On the other hand, the last function of this interface has already a body and so we don’t need to override it. Note that if we want, we can override this function as well.

Alright, now let’s see how we can make a class to implement an interface.

How to implement an interface in Kotlin?

In order to implement an interface using a concrete class, we use a colon and then put the name of that interface after the colon just like the way we do in inheritance.

Note that when a class implements an interface, it must override those abstract members of the interface.

Example: implementing an interface in Kotlin via implements keyword

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

class Cat: Animal{
    override var age:Int = 5
    override fun sound(){
        println("Meow Meow")
    }
}
fun main(){
    
    var cat = Cat()

    cat.sound() 
    cat.sleep()
}

Output:

Meow Meow

Sleeping…

Kotlin Interface Notes:

  • Just like abstract classes, an interface cannot be used to create objects from. This is because they are not fully qualified. But we can create variables of type interfaces to store reference to objects of type classes that implemented those interfaces.
  • Also, unlike abstract classes, an interface cannot have a constructor!

Multiple Inheritance in Kotlin via Interfaces

As mentioned before, a class can implement more than just one interface!

To do that, just put the name of the interfaces after the colon and separate them from each other using comma.

Also, be aware that the target class must override any abstract member of all the interfaces it implements.

Example: interfaces and multiple inheritance

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

interface Runner{
    fun run()
}

class Cat: Animal,Runner{
    override var age:Int = 5
    override fun sound(){
        println("Meow Meow")
    }
    override fun run(){
        println("The cat is running")
    }
}

fun main(){
    
    var cat = Cat()

    cat.run()
    cat.sound() 
    cat.sleep()

}

Output:

The cat is running

Meow Meow

Sleeping…

Using Kotlin Interfaces as the Data type

An interface can be set as the data type of variable, properties, parameters and the return type of functions.

After that, we can create objects from concrete classes that implemented the target interface and store the object into variables of the interface type.

Note: when a variable is of a type of interface, using the variable, we can only access those members that are shared in the target interface as well!

Example: interface as data type

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

interface Runner{
    fun run()
}

class Cat: Animal,Runner{
    override var age:Int = 5
    override fun sound(){
        println("Meow Meow")
    }
    override fun run(){
        println("The cat is running")
    }
}

fun main(){
    
    var cat:Animal = Cat()

    cat.sound() 
    cat.sleep()

}

Output:

Meow Meow

Sleeping…

Here the cat variable is of type Animal interface. This means using this variable, we can’t access the run() function! Because this function is coming from the Runner interface! So basically, only those members that are shared in the Animal interface can be accessed using the cat variable.

But of course you can use the is and as operators to cast the variable and access the run function if you want.

Example: using the is and as operators with Kotlin interfaces

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

interface Runner{
    fun run()
}

class Cat: Animal,Runner{
    override var age:Int = 5
    override fun sound(){
        println("Meow Meow")
    }
    override fun run(){
        println("The cat is running")
    }
}

fun main(){
    
    var cat:Animal = Cat()

    cat.sound() 
    cat.sleep()
    if (cat is Runner){
        cat.run()
    }
}

Output:

Meow Meow

Sleeping...

The cat is running

Example: interface as the data type of a parameter

interface Animal {
    var age:Int 
    fun sound()
    fun sleep(){
        println("Sleeping...")
    }
}

interface Runner{
    fun run()
}

class Cat: Animal,Runner{
    override var age:Int = 5
    override fun sound(){
        println("Meow Meow")
    }
    override fun run(){
        println("The cat is running")
    }
}

fun main(){
    
    var cat:Animal = Cat()

    callSleep(cat)
}

fun callSleep (cat: Animal){
    cat.sleep()
}

Output:

Sleeping…

Kotlin Interface and Inheritance

If there’s a class that inherits from another class and at the same time wants to implement one or more interfaces, the target parent class must appear first and then those interfaces come after and, of course, we use comma to separate them from each other.

For example:

class ClassName: ParentClass, InterfaceOne, interfaceTwo, InterafceN{…}
Facebook
Twitter
Pinterest
LinkedIn

Top Technologies