Default Methods in Interfaces in Java
Why Interfaces Need Default Methods
The reason why the Java 8 release included default methods is pretty obvious.
In a typical design based on abstractions, where an interface has one or multiple implementations, if one or more methods are added to the interface, all the implementations will be forced to implement them too. Otherwise, the design will just break down.
Default interface methods are an efficient way to deal with this issue. They allow us to add new methods to an interface that are automatically available in the implementations. Therefore, we don’t need to modify the implementing classes.
In this way, backward compatibility is neatly preserved without having to refactor the implementers.
Multiple Interface Inheritance Rules
Default interface methods are a pretty nice feature, but there are some caveats worth mentioning. Since Java allows classes to implement multiple interfaces, it’s important to know what happens when a class implements several interfaces that define the same default methods.
public class Car implements Vehicle, Alarm {
// both vehicle and alarm has the same default method signature
}
The code simply won’t compile, as there’s a conflict caused by multiple interface inheritance (a.k.a the Diamond Problem). The Car class would inherit both sets of default methods. So which ones should we call?
To solve this ambiguity, we must explicitly provide an implementation for the methods or to which default interface implementation that we want to use
@Override
public String turnAlarmOn() {
return Vehicle.super.turnAlarmOn();
}
@Override
public String turnAlarmOff() {
return Vehicle.super.turnAlarmOff();
}
Static Interface Methods
In addition to declaring default methods in interfaces, Java 8 also allows us to define and implement static methods in interfaces.
Since static methods don’t belong to a particular object, they’re not part of the API of the classes implementing the interface; therefore, they have to be called by using the interface name preceding the method name.
public interface Vehicle {
// regular / default interface methods
static int getHorsePower(int rpm, int torque) {
return (rpm * torque) / 5252;
}
}
Defining a static method within an interface is identical to defining one in a class. Moreover, a static method can be invoked within other static and default methods.
Furthermore, static methods in interfaces make it possible to group related utility methods, without having to create artificial utility classes that are simply placeholders for static methods.