Java8 – Default methods

Java8 introduces “Default methods” in Interface that allow Developer/API designers to add interface methods without affecting existing functionalities of Interface. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method.

What is problem ?


Let us understand the problem. Developer has developed following API and many other developers are using it and created their concrete implementation.

public interface OlderApi {

public void oldMethod();
}

class OlderApiImpl implements OlderApi {

@Override
public void oldMethod() {
    System.out.println("Implementation of oldMethod");
}
}

 

What if on one fine day Developer of that API decides to provide more features to library and added more interface methods to API ? Surely, this will create nightmare for all the developers who are using this API when updating latest version library to their code.

public interface OlderApi {
    public void oldMethod();
    public void newMethod();
}

Default methods in nutshell


If JDK framework re-engineers to add methods in existing interfaces then surely it will break billions line of code. Default methods provides flexibility to add default implementation of method in interface itself without touching its implementation classes and so make to code backward compatible.

public interface OlderApi {

   public void oldMethod();

   default public void newMethod(){
      System.out.println("Default Implementation of newMethod");
   }
}

This will work even after updating latest OlderApi class in your code without adding its implementation in OlderApiImpl.

There are many default methods added in JDK core libraries. Examples,

Collection<E> interface has following new default methods with default implementation.

default boolean removeIf(Predicate<? super E> var1) { … }
default Stream<E> stream() { … }
default Spliterator<E> spliterator() { … }
default Stream<E> parallelStream() { … }

Interface vs. Abstract class


After introducing Default methods, it seems that Interface and Abstract class are same.But wait both are different.

Abstract class has state associated with it and can define constructor. In contrast, Interface can’t defined its own constructor and default method can be implemented only in the terms of invoking other Interface methods, with no reference to a particular implementation’s state.

Usage patterns of Default methods


  • Remove Optional/Unimplemented method from classes

You have come across many classes that implement interfaces but leave empty implementation for some methods(less used or not relevant methods). This results in unnecessary boiler plate code.

With default methods, you can provide default implementation to interface itself so concrete classes don’t need to explicitly define empty implementation.

  • Inherit multiple behavior

As you know, Java class can implement multiple interfaces and so get default multiple behavior from those interfaces.

Another usage pattern is to compose interfaces such that concrete class gets behavior which it wants to get. Let say, you have behavior1,behavior2,behavior3 provided by three interfaces Interface1,Interface2,Interface3 respectively. Now, you want only behavior1,behavior2 so you need to declare class which implements Interface1 and Interface2 only. Composing interfaces such a way can help to get best out of default methods.

Default Method and Multiple implementation Ambiguity Problems


Since Java class can implements multiple interfaces so there are chances that there exist same name method in two interfaces and class implements both interfaces.

public interface InterfaceA { 

default void duplicateDefaultMethod(){ 
System.out.println("Interface A default method"); 

} 

}

public interface InterfaceB {

default void duplicateDefaultMethod(){
System.out.println("Interface B default method");
}

}

public class ConfictedImpl implements InterfaceA, InterfaceB {

}

The above code will fail to compile.

java: class ConfictedImpl inherits unrelated defaults for duplicateDefaultMethod() from types InterfaceA and InterfaceB.

In order to resolve it, you need to provide default implementation of duplicateDefaultMethod in class it self.

public class ConfictedImpl implements InterfaceA, InterfaceB {

public void duplicateDefaultMethod(){

}

}

 

Further, if you want to call any of interface’s default method. Following code will call default method of InteraceA.

public class ConfictedImplimplements InterfaceA, InterfaceB {

public void defaultMethod(){
InterfaceA.super.duplicateDefaultMethod();
}

}

 

Summary


Default methods enable new functionality to existing interfaces without breaking older implementation of these interfaces.we can perform following when implementing interface having default methods :

  • Not override the default method and will inherit the default method.
  • Override the default method similar to other methods we override in subclass.
  • Re declare default method as abstract, which force subclass to override it.

If you enjoyed this post, I’d be very grateful if you’d help it spread by emailing it to a friend, or sharing it on social media. Thank you!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s