This article explains Default Interface Methods introduced in Java8 and how to use them in multiple inheritance scenarios.
Interface default methods
Prior to JDK 8, an interface could not contain any implementation. Interfaces contain only constants and method signatures.
Beginning JDK 8, it is possible to define default implementation for a method in an interface. These methods are called default methods.
A default method is declared using a keyword “default” and it contains a method body.
A default method is available to all implementing classes of the interface. If the implementation class wants to use it, it can use it or it can ignore the default implementation and create its own implementation.
Even though an interface can now define default methods, the interface must still be implemented by a class if an instance is to be created.
Here is an example of interface with a default method :
package java8; public interface MyIF { int add(int x, int y); //default method default int multiply(int x, int y){ return x*y; } }
The above interface declares an abstract method add() and a default method multiply().
Let’s create a class implementing this interface. Note that, an implementing class is only required to implement the abstract method. The default method can be used as is unless the implementing class wants to change the behaviour.
package java8; public class MyClass implements MyIF { public int add(int x, int y) { return x+y; } }
The above class MyClass implements the MyIF interface and provides implementation of add() method.
Now, if we create an instance of MyClass and call the multiply() method, the default method implementation will be used as shown below :
package java8; public class DefaultMethodDemo1 { public static void main(String[] args) { MyIF intRef = new MyClass(); System.out.println("Sum = " + intRef.add(5,10)); System.out.println("Product = " + intRef.multiply(5,10)); } }
The above program will output :
Sum = 15
Product = 50
Since, the implementing class MyClass didn’t override multiply(), default method behaviour was used.
Multiple inheritance issues with Default methods
Java doesn’t support multiple inheritance of classes, however a class can implement multiple interfaces.
So, what happens when a class implements multiple interfaces with the same default method ?
There could be 3 scenarios here.. here is what will happen in each of the scenarios.
Scenario 1 : Class implements both interfaces without overriding the default method
Let’s create two interfaces InterfaceA and InterfaceB that provide the default method hello() and a class implementing both these interfaces.
Now, the implementing class extends default method behaviour from both interfaces. So, if the implementing class does not implement the hello() method, a compilation error will occur for duplicate method declaration.
Here is the code :
package java8; public interface InterfaceA { default void hello(){ System.out.println("Hello A"); } }
package java8; public interface InterfaceB { default void hello(){ System.out.println("Hello B"); } }
package java8; //Compile error for duplicate default method names public class MultipleDefaultdemo implements InterfaceB, InterfaceA { public static void main(String[] args) { } }
Scenario 2 : Class overrides the default method
If we provide implementation for hello() in MultipleDefaultdemo class, then the default method will be overridden and the class’s hello() method will be used.
It is possible to explicitly refer to a default implementation in an inherited interface using super keyword.
The general form for this is :
InterfaceName.super.DefaultMethodName();
So, we can access the default method hello() in InterfaceA and InterfaceB as follows :
InterfaceA.super.hello();
InterfaceB.super.hello();
Here is the complete example :
package java8; public class MultipleDefaultdemo implements InterfaceB, InterfaceA { public static void main(String[] args) { new MultipleDefaultdemo().hello(); } public void hello(){ System.out.println("Hello Class"); InterfaceA.super.hello(); InterfaceB.super.hello(); } }
Running the above program will generate output :
Hello Class
Hello A
Hello B
Scenario 3 : One interface extends another with same default method
In cases where one interface extends another, with both defining a common default method, the inheriting interface’s version of the method takes precedence.
So, if InterfaceB extends InterfaceA, then InterfaceB’s version of method hello() will be used.
Here is the code for the same :
package java8; public interface InterfaceA { default void hello(){ System.out.println("Hello A"); } }
package java8; public interface InterfaceB extends InterfaceA{ default void hello(){ System.out.println("Hello B"); } }
package java8; public class MultipleDefaultdemo implements InterfaceB, InterfaceA { public static void main(String[] args) { new MultipleDefaultdemo().hello(); } }
Running this will produce output :
Hello B
Difference between Interface with Default method and Abstract class
When we add default method to an interface, it looks like an abstract class, but they are not the same.
An abstract class can have constructors, instance variables, concrete methods, but we can’t have instance variables or constructors in the interface.
An interface with single default method can be used to refer to a lambda expression, but an abstract class cannot be used to refer to lambda expressions.
Read more on the difference between Interface with Default method and Abstract class here :
Interface with default method vs Abstract class
You may also like :
© 2015 – 2016, https:. All rights reserved. On republishing this post, you must provide link to original post
#