In today’s TL;DR series, we’ll talk about default methods. Click here to know more about the TL;DR series.
Java 8 introduced the ability to add method implementation to interfaces. These are called “default methods” ( or defender methods).
This allow interfaces to define implementations that will be used (as a default) in the situation where a concrete class fails to provide an implementation for that method.
A concrete class implementing an interface must implement all the interface’s defined methods. If a interface were to change, all implementing classes will need to be updated. The introduction of default methods allows developers to add new methods without breaking existing code.
See It In Action
With default implementations, we can create an instance of the class implementing the InterfaceOne interface and invoke it like we can a regular instance methods. A interface can provide implementations for more than one method. Those with a single default method are sometimes called a functional interface.
The Diamond Problem
Java only allows the extension of one class. If it allowed for two or more, we would run into the “Diamond Problem”. If ConcreteOne extended two interfaces, InterfaceOne and InterfaceTwo, and both had two methods with the exact same signature, which would method would be included in the concrete class?
Java does allow a class to implement multiple classes, so how do we get around this problem now (with default interfaces)?
Java throws a compile-time error:
“Duplicate default methods named doSomething with the parameters () and () are inherited from the types InterfaceTwo and InterfaceOne”
If a class implements two or more interfaces and there exists methods with the same signature among these interfaces, then the developer is forced to provide an implementation in the concrete class.
In the above situation, if you do want to invoke a specific interface’s default implementation, you can do so using the super keyword on the interface:
Abstract v.s. Interfaces
The addition of default interfaces does blur the line between abstract classes (with default implementations) and interfaces (also with default implementations). Below is a brief list of differences between an abstract class and interface with respect to default implementations.
- Have state associated with them and their implemented methods can access class and instance variables.
- Can invoke other abstract methods.
- Interfaces do not have state and their implementations cannot access can only access class variables.
- Default implementations can only invoke other methods with default implementations.
- Useful for providing implementations of helper or utility methods.
Abstract classes still have a role to play in the java ecosystem. They provide a base for sub-classes and many other behaviors which are not replaced by default implementations. That being said, there are many stateless or utility like behaviors that may now be better suited as a default implementation on an interface.