Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Using Interfaces

To use an interface, we must make a class implement that interface. The syntax for this is very similar to the syntax for inheriting from a superclass. You must follow the class name with a colon, then the name of the interface.

Let’s return to the GUI scenario discussed earlier, where we introduced the Clickable interface. We can create a class Button that implements this interface like so:

class Button : Clickable {
    override fun click() {
        ...
    }
}

Because Button implements the Clickable interface, it must override click() explicitly and provide an implementation for this method. Failing to do so would be a compiler error.

Notice the lack of parentheses after Clickable. When we are creating a subclass, we need to specify not only the name of the superclass but also which superclass constructor we want to invoke. Hence the superclass name is always followed by parentheses, possible containing arguments that will be passed to the superclass constructor.

Implementing an interface is simpler, because interfaces don’t have constructors. All we need to do when implementing an interface is name that interface.

A slightly more realistic version of the example above might look like this:

class Button : Widget(), Clickable {
    override fun click() {
        ...
    }
}

Here, Widget represents a superclass, possibly abstract, from which all GUI components should inherit. It provides Button with some properties to represent state, and some methods. In this case, we specify that the default constructor of Widget will be invoked as part of the process of creating a Button object.

In this scenario, Clickable represents an additional contract that Button objects must fulfil. We can say that Button is primarily a kind of widget, but it also has the more general capability of being clickable.

Tip

When you see a list of type names appearing after a colon in a class definition, you can say immediately that the first name in the list is either a superclass or an interface, and all subsequent names are interfaces.

If the first type name is followed by parentheses, possibly containing constructor arguments, then you know that it is the name of the superclass, rather than an interface.

Task 17.3

  1. Edit the file Interfaces.kt, in the tasks/task17_3 subdirectory of your repository.

    At the location indicated by the relevant comment, add an interface named Printable. This should specify a single abstract method named print(), with an empty parameter list.

  2. At the location indicated by the relevant comment, add a class named Document with a val property named filename, of type String.

  3. Make your Document class implement the Printable interface. Your implementation of print() should display the word “Printing” on the console, followed by the document’s filename.

  4. Compile and run the program.