Exploring Default Methods In Java 8

Introduction

Java 8 brought lots of features and one of them is the ‘default’ methods. The default methods are methods within the interface that can have a body. In the prior versions of Java, we can only have abstract methods, and if a new method is created then all implementing classes must implement the new method.

The biggest advantage of the ‘default’ method is that without any effect on the implementation classes we can add functionalities to the interface.

The default methods will be very useful when we try to implement the ‘Template’ method Design Pattern, where we can abstract the common functionality with a body to the base interface as the default method.

Example’s

When we extend an interface with a default method in it, we can override the default can have our own functionality, simply call the default method without overriding it. Let’s understand by example

public interface A {
    default void show() {
	    System.out.println("Inside Show");
    }
}

The show method is having a ‘default’ keyword which indicates it’s a default method.

In this example, we are calling the default method as is without overriding it.

public class C implements A {

	public static void main(String[] args) {
		C c = new C();
		c.show();
	}
}

In this example, we are overriding the ‘show’ method and providing the behavior.

public class C implements A {
	
	@Override
	public void show() {
		System.out.println("Inside C show");
	}

	public static void main(String[] args) {
		C c = new C();
		c.show();
	}
}

Output: Inside C show

Issues with ‘default’ method

The default method has an issue, the multiple inheritance ambiguity. In the same example as above, let's create another interface named ‘B’.

public interface B {

	default void show() {
		System.out.println("Inside Show");
	}
}

And modify the class ‘C’ and implement both A and B

public class C implements A, B {
	
}

The class ‘C’ now will fail to compile and give an error “Duplicate default methods named show with the parameters () and () are inherited from the types B and A”

The class ‘C’ will not compile because of the classic Diamond problem, to resolve the issue we have to override the ‘show’ method.

public class C implements A, B {
	
	public void show() {
		System.out.println("Inside C Show");
	}
	
	public static void main(String[] args) {
		C c = new C();
		c.show();
	}
}

Also, to invoke the specific Interface version of ‘show’, we have to do the following

public class C implements A, B {
	
	public void show() {
		System.out.println("Inside C Show");
		A.super.show();
		B.super.show();
	}
	
	public static void main(String[] args) {
		C c = new C();
		c.show();
	}
}

Default methods are a great addition in my opinion and help in abstracting the common functionality.

Thank You for reading and I hope you like the article.