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.
How do we define default and static methods?
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 important 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).
Why do we need default and static methods?
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.
Default methods and multiple inheritance ambiguity problem
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() { } }
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(); } }
I hope you find this post informative and useful. Comments are welcome!!!.