Skip to content
Theory · Interfaces, enums and records · lesson 3 of 8

default methods

In the previous lesson, a class that implements an interface wrote each of its methods itself. Because of this rule, an interface is hard to change.

Back to the job ad. Say the employer adds a new duty to it: report after each delivery. All the couriers who already took the job break the deal at once, because they cannot do this. Java works the same way: add a new method without a body to Courier, and every class that implements Courier stops compiling.

The employer acts smarter and attaches a ready instruction to the new duty: if you have no way of your own, write "Delivered" in the chat. Those who can report in their own way do so, and the rest follow the instruction. In Java, such an instruction is a default method. To watch only the report, let's leave one method in Courier, report:

JAVA
public class Main {
    public static void main(String[] args) {
        Courier c = new Cyclist();
        c.report(); // Delivered
    }
}

interface Courier {
    default void report() {
        System.out.println("Delivered");
    }
}

class Cyclist implements Courier {}

Let's go through the program step by step:

  1. In the Courier interface, the report method is written with a body, and the word default stands before it.
  2. The Cyclist class implements Courier but has no report of its own, and the compiler does not object.
  3. c.report() runs the body from the interface and prints Delivered.

A method with a body in an interface

A default method is an interface method with a body and the word default before it. Such methods appeared in Java 8.

What matters about default methods:

  • a class gets a default method ready-made and does not have to write it;
  • a default method, like a method without a body, is public;
  • a class can write its own version: then it overrides the default method, like a parent's method in the previous theme.

Interviewers often ask why default methods appeared. The answer: to add new methods to an interface without breaking the classes that already implement it.

Which method runs

There is one rule. On a call, Java first looks for the method in the object's class, then in its parents. Only if none of them has written its own method does the interface's default method run. A courier who has a way of their own to report does not read the instruction.

The widget has two couriers: Cyclist has no report of its own, and Drone has one. Press "Next step" and watch whose frame lands on top at each call.

LiveWhose report runsstep 1 of 7 · frames: 1

a refers to a Cyclist object, and the Cyclist class has no report of its own.

The top frame is the method running now

Both calls are written the same way, through a variable of type Courier. The object decided which report to run: for Cyclist only the instruction from the interface was found, and Drone reported in its own way. This is the same polymorphism as with the universal remote.

Here the instruction picture is not exact. On a paper instruction, a courier can tick off how many reports they have already sent. A default method has no such paper: an interface keeps no data of an object. The next section is about that.

Abstract class or interface

Now both an interface and an abstract class can have methods with a body. So how do they differ? It is one of the most common questions at a Java interview.

Abstract classInterface
Object fieldsyes, each object has its own valuesno, an interface's fields are shared constants
Constructoryesno
How many a class can takeone parent through extendsany number through implements

Behind the table there is a different meaning:

  • an abstract class answers the question "what is it?": a cyclist and a van driver are employees, and each has a name and a number of deliveries;
  • an interface answers the question "what can it do?": both an employee and a drone can deliver.

Hence the rule of choice. If related classes need common fields and a constructor, take an abstract class. If quite different classes will get the ability, take an interface. A class can combine both: class Van extends Vehicle implements Courier.

Common mistake

Someone tried to keep the number of reports in an interface field:

JAVA
interface Courier {
    int reports = 0;
    default void report() {
        reports++; // ✗
        System.out.println("Delivered");
    }
}
TEXT
error: cannot assign a value to static final variable reports

The program does not compile. A field in an interface is a constant: the compiler added the words static and final itself, and the message names both. An interface cannot keep an object's data, such as the number of its reports. Such a field is declared in a class, and if several related classes need it, in their common abstract parent.

Key points

  • A default method is an interface method with a body: a class gets it ready-made and can override it.
  • On a call, Java first looks for the method in the object's class and its parents, and the default method runs only if none of them has its own.
  • An abstract class has object fields and a constructor, while an interface's fields are shared constants; but a class can implement any number of interfaces.
  • An abstract class describes what an object is, and an interface describes what it can do.