In this article, you will learn what an interface is, how to implement it, and the advantage of using interface over abstract classes.

Interface

Interface is very similar to Abstract classes, because the interface can also contain both abstract and non-abstract properties and functions and it cannot be instantiated.

We prefer to use interfaces rather than abstract classes because Kotlin does not support multiple inheritances i.e it does not allow us to inherit from more than one parent class.  However, we can implement multiple interfaces.

Let’s see an example of an interface:

interface Vehicle {
    fun drive() {
        println("Let's drive")
    }

    fun park()
}

Key points:

  1. Interface is declared using the keyword interface.
  2. In the above example, the method park() is not implemented. In interface, the methods with no implementation are by default abstract, so it is not necessary for us to explicitly mark the method as abstract.

fun park() is equivalent to abstract fun park() in the interface.

  1. Interface cannot be instantiated so it cannot have constructors. Though abstract class also cannot be instantiated, it can still have a constructor.
  2. A class can implement more than one interface.

Implementing Interface

Implementing an interface is very similar to extending an abstract class. The abstract methods in the interface must be implemented by the child class using override keyword as shown in the example below.

interface Vehicle {
    fun drive() {
        println("Let's drive")
    }

    fun park()
}

class Car(val name: String, val modelNumber: String, val color: String) : Vehicle {
    override fun park() {
        println("Let's park $name $modelNumber car of $color color")
    }
}

fun main(args: Array<String>) {
    val car = Car("BMW", "S3", "Red")
    car.drive()
    car.park()
}

Implementing more than one interface

Let’s see an example where a class Car implements interface Vehicle and Owner. The class Car must implement all the abstract methods from both the interfaces.

interface Vehicle {
    fun drive() {
        println("Let's drive")
    }

    fun park()
}

interface Owner {
    fun getOwnerName()
}

class Car(val name: String, val modelNumber: String, val color: String) : Vehicle, Owner {
    override fun park() {
        println("Let's park $name $modelNumber car of $color color")
    }

    override fun getOwnerName() {
        println("The owners name is Sophia")
    }
}

fun main(args: Array<String>) {
    val car = Car("BMW", "S3", "Red")
    car.drive()
    car.park()
    car.getOwnerName()
}

In the given example, the interfaces Vehicle and Owner have different methods. What if the interfaces have the same method? How would we deal with such conflicts? 

Resolve Conflict  

Well, we can use the super keyword to specify which method we want to use when we have methods in our interfaces with the same name. Let’s see an example of how we can use super to resolve the conflict.

interface Vehicle {
    fun drive() {
        println("Let's drive")
    }

    fun park()
}

interface Owner {
    fun getOwnerName()
    fun drive () {
        println("Sophia is driving")
    }
}

class Car(val name: String, val modelNumber: String, val color: String) : Vehicle, Owner {
    override fun drive() {
        super<Owner>.drive()
    }

    override fun park() {
        println("Let's park $name $modelNumber car of $color color")
    }

    override fun getOwnerName() {
        println("The owners name is Sophia")
    }
}

fun main(args: Array<String>) {
    val car = Car("BMW", "S3", "Red")
    car.drive()
    car.park()
    car.getOwnerName()
}

In line number 17, you can see that the interface name is specified as Owner, which means the drive method of Owner class is called.

Click on the next button to continue reading.

Category
Tags

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *