In Java 7 interfaces, we have declarations only. Although we have static and instance methods, we don’t have implementations for interfaces. Because of which we won’t be able to achieve Multiple Inheritance through these interfaces.
But in Java 8, interfaces have default implementations along with declarations. It cannot have constructors and member variables. Java 8 interface includes static methods and default methods in an interface.
For creating a default method in Java, the method signature should be preceded by “default” keyword.
Java 8’s default method syntax:
1 2 3 4 5 6 7 8 9 |
package com.wavelabs.test; public interface Test { default void method() { System.out.println("Interface in Java 8."); } } |
When a class is implementing an interface, we don’t have to provide an implementation for default interface. This feature helps us in extending interfaces with multiple methods. For this, we need default methods in an interface.
If two interfaces have same default method signature then, you can override any of the method signatures.
Abstract vs. default methods:
When we have an abstract method and default method with same method signature, the abstract method overrides the default methods implementation.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.wavelabs.test; interface interface1 { public void method(); } interface interface2 { default void method() { System.out.println("default method in interface2."); } } interface interface3 { default void method() { System.out.println("default method in interface3."); } } public class AbstractAndDefaultMethodDemo implements interface1, interface2, interface3 { public static void main(String[] args) { new AbstractAndDefaultMethodDemo().method(); } public void method() { System.out.println("Implementation for abstract method."); } } |
Static methods in Interface:
Default methods and static methods are same except we cannot override in the implementation class.
We know that in Java (until JDK 7), inheritance in Java was supported by extends keyword which is used to create a child class from a parent class. You cannot extend from two classes.
Until Java 7, interfaces were only available for declaring the things by which the implementation classes must implement.
There was no specific behaviour for that interfaces. Even after a class was capable of implementing as many as interfaces as it wants, it was not appropriate to be called as Multiple inheritances.
But in Java 8 default methods, interfaces have behaviours as well. So if a class wants to implement two interfaces, both define default methods, then it is necessarily inheriting behaviours from two parents which are Multiple inheritances.
For instance, in the below code, Button class does not define any of its own behaviour. It is inheriting behaviour from parent interfaces. That’s Multiple Inheritance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.wavelabs.test; interface Clickable { default void click() { System.out.println("It's clickable."); } } interface Accessible { default void access() { System.out.println("It's accessible."); } } public class Button implements Clickable, Accessible { public static void main(String[] args) { Button button = new Button(); button.access(); button.click(); } } |
Conflict:
In the above example, we have two different interfaces and two different methods, so there is no conflict. If both interfaces define a new method with the same name which method will be invoked when Button instance will call its name. This is a conflicting situation!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.wavelabs.test; interface Clickable { default void click() { System.out.println("It's clickable."); } } interface Accessible { default void click() { System.out.println("It's accessible."); } } public class Button implements Clickable, Accessible { public static void main(String[] args) { Button button = new Button(); // button.click(); // button.click(); } } |
So for the above conflict, the caller class must decide which click() method it wants to invoke.
Here, Java 8 interfaces will resolve the conflicts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.wavelabs.test; interface Clickable { default void click() { System.out.println("It's clickable."); } } interface Accessible { default void click() { System.out.println("It's accessible."); } } public class Button implements Clickable, Accessible { public static void main(String[] args) { Button button = new Button(); } @Override public void click() { Accessible.super.click(); } } |
In the above code, I’m overriding the Accessible interface behaviour. If you want you can override any of the above interface methods like
1 |
Accessible.super.click() |
Or
1 |
Clickable.super.click(); |
Now, Java 8 provides default implementations for interfaces so that Multiple Inheritance can be achieved by overriding the necessary behaviours. It’s very important to implement any number of interfaces in any number of classes.