Authors Top

If you have a few years of experience with the Kotlin language and server-side development, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

In this quick tutorial, we’ll learn how to extend a class and implement interfaces simultaneously in Kotlin.

2. Introduction to the Problem

In Java, we have the extends and the implements keywords for extending a class and implementing interfaces. However, on Kotlin’s side, we don’t have these keywords.

So how to inherit a class and implement interfaces would be one of the frequently asked questions for experienced Java programmers who have newly come to the Kotlin world.

As usual, we’ll learn how class inheritance and interface implementation are written in Kotlin through an example.

Let’s say we have a Person class and two interfaces:

open class Person(private val firstName: String, private val lastName: String, val age: Int) {
    fun fullName(): String {
        return "$firstName $lastName"
    }
}

interface BaeldungReader {
    fun readArticles(): String
}

interface BaeldungAuthor {
    fun writeArticles(): String
}

As the code above shows, the Person class has the open keyword. This indicates that the Person class can be inherited.

The two interfaces are easy to understand. Each of them has defined a method.

Now, our task is to create a subclass of Person and implement the two interfaces above in Kotlin.

For simplicity, we’ll use unit test assertions to verify if our class works as expected.

Next, let’s see it in action.

3. Extending a Class and Implementing Two Interfaces

First, like Java, a Kotlin class can only inherit one superclass, but it can implement multiple interfaces.

Kotlin uses the colon character “:” to indicate both inheritance and interfaces’ implementation. So, for example, class MyType(…) : SuperType(…) means the MyType class inherits the SuperType class.

Similarly, MyType(…) : Interface1, Interface2 indicates the MyType class implements Interface1 and Interface2.

If we would like to make MyType inherit SuperType and implement the interfaces, we can put them together after the colon character separated by commas: class MyType(…) : SuperType(…), Interface1, Interface2.

A concrete example can make this clear quickly.

Next, let’s create a Developer class as the subclass of our Person class and make it implement BaeldungReader and BaeldungAuthor interfaces:

class Developer(firstName: String, lastName: String, age: Int, private val skills: Set<String>) 
  : Person(firstName, lastName, age), BaeldungAuthor, BaeldungReader {
    override fun readArticles(): String {
        return "${fullName()} enjoys reading articles in these categories: $skills"
    }

    override fun writeArticles(): String {
        return "${fullName()} writes articles in these categories: $skills"
    }
}

As the Developer class shows, we put the superclass and two interfaces after the colon character. It’s worth mentioning the order of the superclass and interfaces after the colon character doesn’t matter.

Of course, as the interfaces have defined readArticles() and writeArticles() functions, the Developer class must implement them. Unlike Java, when we override functions in Kotlin, we use the override keyword instead of the @Override annotation.

Next, let’s create a test to check if our Developer class works as expected:

val developer: Developer = Developer("James", "Bond", 42, setOf("Kotlin", "Java", "Linux"))
developer.apply {
    assertThat(this).isInstanceOf(Person::class.java).isInstanceOf(BaeldungReader::class.java).isInstanceOf(BaeldungAuthor::class.java)
    assertThat(fullName()).isEqualTo("James Bond")
    assertThat(readArticles()).isEqualTo("James Bond enjoys reading articles in these categories: [Kotlin, Java, Linux]")
    assertThat(writeArticles()).isEqualTo("James Bond writes articles in these categories: [Kotlin, Java, Linux]")
}

In the test, we first created a developer instance by calling Developer‘s constructor. Then we’ve verified that developer should be an instance of Person, BaeldungReader, and BaeldungAuthor.

Finally, we checked if the overridden functions return the expected result.

The test passes if we give it a run.

4. Conclusion

In this article, we’ve learned how to extend a class and implement interfaces at the same time in Kotlin.

As always, the full source code for the examples is available over on GitHub.

Authors Bottom

If you have a few years of experience with the Kotlin language and server-side development, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!