Start learning free

LESSON 190 OF 348 · OBJECT-ORIENTED PROGRAMMING

Interfaces in Kotlin: Contracts, Override and Multiple Interfaces

Lesson Read the full explanation

TL ; DR:

An interface is a pure contract — a list of methods that a class promises to implement, with no shared data and no shared code. Unlike inheritance ("is a"), interfaces express "can do".


interface Speaker {
    fun speak()
}
class Dog : Speaker {
    override fun speak() {
        println("Woof")
    }
}


Full lesson:

An interface defines what a class can do, not how it does it or what it is. A Truck, a Robot, and a Drone aren't the same kind of thing — but they can all Move(). You'd put Move() in a Movable interface and have each one implement it.

Interface vs abstract class

Abstract classInterface
Has fieldsYesUsually no
Has method bodiesYes (some)No (or default impls only)
Multiple "inheritance"Usually noYes — a class can implement many interfaces
Models"is a""can do"

A class inherits from at most one parent class but can implement many interfaces. That's why interfaces are the right tool for cross-cutting capabilities like Comparable, Serializable, Iterable, etc.

The language landscape

  • C# / Java — first-class interface keyword. C# uses : for both inheritance and implementation; Java uses extends for inheritance and implements for interfaces.
  • Python — no separate interface; abstract base classes (ABCs) with all-abstract methods serve the same role.
  • JavaScript — no interface keyword in plain JS (TypeScript has it). The convention is a stub class.
  • C++ — a class with only pure-virtual methods is an interface. Multiple inheritance lets a class implement several.

Your task

The Speaker interface (or interface-like base) is already declared. Create a Dog class that implements it, with a speak() method that prints "Woof".

Expected output:

Woof
STEP 1 OF 2
    Ctrl + Enter to check

    KOTLIN · OBJECT-ORIENTED PROGRAMMING

    Interfaces in Kotlin, explained

    What an interface is

    An interface lists what a class can do without saying how it does it. A Dog, a Robot and a Drone are different kinds of things, yet each might be able to speak or move. If the ability is written as an interface, any class can promise to provide it, and code that only needs the ability can work with all of them.

    Inheritance models "is a" (a dog is an animal). An interface models "can do" (a dog can speak). The lesson's interface is one function with no body:

    interface Speaker {
        fun speak()
    }
    

    A function without a body in an interface is abstract, and every class that implements the interface must provide it. You don't write the keyword abstract here: inside an interface it is implied.

    Step by step: the exercise

    The lesson supplies the Speaker interface and a Solution class whose mainFunction creates val rex: Speaker = Dog() and calls rex.speak(). The output must be Woof, so you write the Dog class.

    1. Declare Dog and list Speaker after a colon. Kotlin uses the same colon for extending a class and for implementing an interface. Note that there are no parentheses after Speaker: an interface has no constructor, so there is nothing to call. A class, by contrast, needs them, as in : Animal().
    2. Implement speak with override. Write override fun speak() and print Woof with println. The keyword is mandatory in Kotlin, which makes it clear that the function comes from a contract.

    The variable is declared as Speaker but holds a Dog. The call rex.speak() is allowed because Speaker has speak(), and it runs the version in Dog.

    The solution in Kotlin

    interface Speaker {
        fun speak()
    }
    
    class Dog : Speaker {
        override fun speak() {
            println("Woof")
        }
    }
    
    class Solution {
        fun mainFunction() {
            val rex: Speaker = Dog()
            rex.speak()
        }
    }
    

    Three details here are easy to trip over:

    • No constructor call for an interface. Writing class Dog : Speaker() fails with this type does not have a constructor. And creating an interface directly, as in Speaker(), fails with interface 'interface Speaker : Any' does not have constructors.
    • override is not optional. A fun speak() in Dog without it gives 'speak' hides member of supertype 'Speaker' and needs an 'override' modifier.
    • Missing implementations are errors. A class that lists Speaker but has no speak() gets class 'Cat' is not abstract and does not implement abstract member.

    One class, many interfaces

    A Kotlin class has at most one superclass but can implement as many interfaces as it likes. List them after the colon, separated by commas:

    interface Speaker { fun speak() }
    interface Named { val name: String }
    
    class Dog : Speaker, Named {
        override val name = "Rex"
        override fun speak() { println("Woof") }
    }
    
    class Robot : Speaker {
        override fun speak() { println("Beep") }
    }
    
    fun greet(s: Speaker) = s.speak()
    
    fun main() {
        greet(Dog())
        greet(Robot())
    }
    

    This prints Woof and then Beep. The function greet accepts anything that is a Speaker. It doesn't know or care whether it received a dog or a robot, and a new class can be added later without changing greet. The example also shows that an interface can declare a property, here name, which the class overrides.

    Interface versus abstract class

    Abstract classInterface
    Constructor and stored stateYesNo stored state
    Members with bodiesYesYes, as default implementations
    How many a class can useOne parentAny number
    Models"is a""can do"

    Kotlin interfaces may contain functions with bodies, which act as defaults. A class can use them as they are or override them:

    interface Mover {
        fun move() = println("moving")
    }
    

    If two interfaces give the same function a default body and a class implements both, the compiler stops you with class 'C' must override 'hi' because it inherits multiple interface methods for it. The class resolves it by overriding the function and choosing which parent to call with super<A>.hi().

    Common mistakes

    • Parentheses after the interface name. They belong only after a class in the supertype list.
    • Leaving out override. The compiler treats the function as a clash with the interface's.
    • Forgetting a member. Implement every function and property that has no default.
    • Trying to create an interface instance. Create the implementing class, and use the interface as the variable's type.
    • Wrong output text. The lesson expects exactly Woof.

    Key takeaways

    • An interface is a contract of "can do" members, declared with interface.
    • A class implements it with a colon, no parentheses, and marks each implementation override.
    • A class can implement many interfaces but extend only one class.
    • A variable typed as the interface can hold any implementing object, and calls run that object's version.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free