What are Default Methods?
Before Java 8, we could only declare abstract methods in an interface. However, Java 8 introduced the concept of default methods. Default methods are methods that can have a body. The most important use of default methods in interfaces is to provide additional functionality to a given type without breaking down the implementing classes.
Before Java 8, if a new method was introduced in an interface then all the implementing classes used to break. We would need to provide the implementation of that method in all the implementing classes.
However, sometimes methods have only single implementation and there is no need to provide their implementation in each class. In that case, we can declare that method as a default in the interface and provide its implementation in the interface itself.
public interface Vehicle {
void cleanVehicle();
default void startVehicle() {
System.out.println("Vehicle is starting");
}
}
public class Bus implements Vehicle {
@Override
public void cleanVehicle() {
System.out.println("Cleaning the vehicle");
}
public static void main(String args[]){
Bus bus = new Bus();
bus.cleanVehicle();
bus.startVehicle();
}
}
The above class only needs to implement the abstract method. When we call the default method, the code defined in the interface is executed.
How do we resolve issues raised due to the default method defined in interfaces?
Let's say we have two interfaces InterfaceOne and InterfaceTwo.
InterfaceOne.java
public interface InterfaceOne {
default void printSomething() {
System.out.println("I am inside interface one");
}
}
InterfaceTwo.java
public interface InterfaceTwo {
default void printSomething() {
System.out.println("I am inside interface two");
}
}
Let's define the Main class that will implement both these interfaces. Now you should question yourself:
If you just implement both interfaces and do not provide the implementation to default methods, the program won't compile because of the Diamond problem in Java. To resolve the compilation issue, we will have to implement the printSomething()
method as shown below:
Main.java
public class Main implements InterfaceOne, InterfaceTwo {
@Override
public void printSomething() {
//Option 1 -> Provide your own implementation.
System.out.println("I am inside Main class");
//Option 2 -> Use existing implementation from InterfaceOne or InterfaceTwo or both.
InterfaceOne.super.printSomething();
InterfaceTwo.super.printSomething();
}
public static void main(String args[]){
Main main = new Main();
main.printSomething();
}
}