We will start with Introduction to default and static methods then how to define default and static methods, why we need default and static methods and end the post with default methods and multiple inheritance ambiguity problem.
Java 8 introduced default and static methods in interfaces. These features allow us to add new functionality in the interfaces without breaking the existing contract for implementing classes.
Default method has default
and static method has static
keyword in the method signature.
public interface InterfaceA {
double someMethodA();
default double someDefaultMethodB() {
// some default implementation
}
static void someStaticMethodC() {
//helper method implementation
}
}
Few points for default method
- You can inherit the default method.
- You can redeclare the default method essentially making it abstract.
- You can redefine the default method (equivalent to overriding).
Consider an existing Expression
interface with existing implementation like ConstantExpression
, BinaryExpression
, DivisionExpression
and so on. Now, you want to add new functionality of returning the signum of the evaluated result and/or want to get the signum after evaluating the expression. This can be done with default and static methods without breaking any functionality as follows.
public interface Expression {
double evaluate();
default double signum() {
return signum(evaluate());
}
static double signum(double value) {
return Math.signum(value);
}
}
You can find the full code on Github.
Java support multiple inheritance of interfaces. Consider you have two interfaces InterfaceA
and InterfaceB
with same default method and your class implements both the interfaces.
interface InterfaceA {
void performA();
default void doSomeWork() {
}
}
interface InterfaceB {
void performB();
default void doSomeWork() {
}
}
class ConcreteC implements InterfaceA, InterfaceB {
}
The above code will fail to compile with error: unrelated defaults for doSomeWork()
from InterfaceA
and InterfaceB
.
To overcome this problem, you need to override the default method.
class ConcreteC implements InterfaceA, InterfaceB {
@override
public void doSomeWork() {
}
}
If you don't want to provide implementation of overridden default method but want to reuse one. That is also possible with following syntax.
class ConcreteC implements InterfaceA, InterfaceB {
@override
public void doSomeWork() {
InterfaceB.super.doSomeWork();
}
}