You are here
Home > Java 8 >

Default Method in Interface

Default Method in InterfaceAs we are aware that till JDK 7 we couldn’t include implemented method inside an interface. In other words, there was no provision to have a method body inside a method of an Interface. But for those who are reading Default Methods for the first time it will be very surprising. The surprise is that we can now include an implemented method inside an Interface. Therefore, we can also have an implemented method inside an interface. Here, we are talking about default methods. The most use of default method in interface is to provide additional functionality to a given type without breaking down the implementing classes.

In this article, we are going to take a deeper look on default method in Interface and other related concepts as well.

Default Method in Interface

If we have an implemented method inside an interface with default keyword, then we will call it as a Default method. We also call it defender method or virtual extension method. Default methods in interfaces were introduced in JDK 8. For example, in the below code, walks() is a default method inside interface Human. Further, we can’t force Implementing classes to override this method.

interface Human {
   void speaks();
   void eats();
   default void walks(){
      System.out.println("Every human follows the same walking pattern");
   }
}

Implementing classes are free to provide their own implementation of the default method. If the implementing class doesn’t override the default method, it means that the class doesn’t need that functionality in it.

How to decide which method should be default?

Let’s understand it from the above example. Why we have taken the walks() method as default, but not the speaks() & eats(). There are high chances that speaking & eating habit of a human being can have specialization in future like EnglishSpeaker, FrenchSpeaker or Vegetarian, Non-vegetarian etc. However, walking habit of a human being is more common & there are very less chances of having variations in walking. Therefore, we have kept walks() as a default method. Even if there are chances to have variation, the implementing classes can have their own implementation of it.

Therefore, declare a method as default which has very less or negligible chances to be overridden by subclasses. This is only the best practice but should not be a thumb rule.

Why do we need Default Methods/ Advantages of defining Default Method ?

The primary idea of including default method in interface is that don’t force the implementing classes to override it. Till JDK 1.7, all implementing classes were supposed to override the method declared in the interface and provide the concrete implementation of the methods. But after introduction of default methods in Interfaces, implementing classes are free to either override it or not as per the required behavior.

Suppose we have an Interface A with abstract methods m1(), m2(), m3() in an existing application. Implementing classes A1, A2, A3 are overriding all three methods of interface A and provide their own implementations as per required functionalities. After some time a new change request comes which needs to add a method m4() in interface A but only implementing class A2 needs to override it & classes A1, A3 don’t need the m4() behavior. In this scenario we can declare method m4() as a default method and override it in class A2 only. Compiler will not complain any more to override method m4() in classes A1 & A3. In this way we will not have any unnecessary modification on other classes.

Default methods offer us to add new methods to an interface that will be available in the implementations automatically. Thus, there’s no need to modify the implementing classes after including a default method.

Here we will also follow one of our design principle “Open-closed principle” to some extent. It says our class should be open for extension but closed for modification. For example, below code is valid without any compilation problem.

public interface A {

    void m1();
    void m2();
    void m3();
    default void m4() {
      System.out.println(" I am a default method ");
    }
}

public class A1 implements A {

    @Override
    public void m1() {
      System.out.println("m1() from class A1");
    }

    @Override  
    public void m2() {
      System.out.println("m2() from class A1");
    }

    @Override
    public void m3() {
      System.out.println("m3() from class A1");
    }
}

public class A2 implements A {

    @Override
    public void m1() {
      System.out.println("m1() from class A2");
    }

    @Override
    public void m2() {
      System.out.println("m2() from class A2");
    }

    @Override
    public void m3() {
      System.out.println("m3() from class A2");
    }

    @Override
    public void m4() {
      System.out.println("m4() from class A2");
    }
}

public class A3 implements A {

    @Override
    public void m1() {
      System.out.println("m1() from class A3");
    }

    @Override
    public void m2() {
      System.out.println("m2() from class A3");
    }

    @Override 
    public void m3() {
      System.out.println("m3() from class A3");
    }
}

How can a default method save effort in writing codes?

We have discussed the above example with 3 implementing classes. Imagine in real time projects where we have more than 50 implementing classes. If there were no default methods we would have modified more than 50 classes unnecessarily. Other solution to this problem before JDK 1.8 was to create new Interface and declare the new method m4() in it, then override it wherever required but this process will take much time ,effort ,cost & lots of modifications in the code. Thanks to Java Community for introducing default methods inside Interfaces to make programmer’s life easy.

Suppose we have very common functionality that might be required by implementing classes in future as well. Then we can incorporate this in the default method of the Interface.

Resolution of Diamond Problem in context of Default methods

As all of us know that Java doesn’t support multiple inheritance & we make use of interfaces in place of classes to get this feature to some extent. Suppose we have two interfaces A & B and both of them are having the default method m1() with the same method signature. Our implementing class is going to implement both the interfaces to have multiple inheritance feature. Now compiler will start complaining as it will not be able to understand m1() method of which interface needs to be overridden. We call this ambiguity as diamond problem.

interface A {
    default void m1() {
      System.out.println("I am default method");
    }
}

interface B {
    default void m1() {
      System.out.println("I am default method");
    }
}

class Test implements A, B {
// complier is unable to find out which m1() has to be overridden, so compile time error
}

In order to solve this ambiguity & make compiler happy, either we can provide our own implementation of m1() or provide the reference of the interface whom method m1() needs to be overridden. For example, observe the code below:

Solution #1

class Test implements A, B {
    public void m1() {
      System.out.println("I have my own implementation, I am not copy of default m1()");
    }
}

Solution #2

class Test implements A, B {
    public void m1() {
      A.super.m1(); //I want to override m1() of interface A
    }
}

Difference between Interface & Abstract class after introduction of default Methods

The major difference between the Interface & an abstract class before JDK 1.8 was that all the methods in an Interface are abstract by default while in an abstract class it is not necessary that all methods are abstract. After introduction of default methods in Interface starting from JDK 1.8 this difference becomes false. It doesn’t mean that both are similar now as we still have many differences between them. Let’s go through the table below to see the differences which are still in place.

Default Methods in Interfaces

Important Note on Default Methods  

  • We can have Default methods(method with default keyword) only inside Interfaces. They are not allowed inside classes even if it is implementing class of that Interface.
  • Any method inside an Interface can’t be declared default & static together. Default methods can’t be static & static methods can’t be default.
  • Similar to regular interface methods default methods are also public implicitly. Hence, we don’t need to specify the public modifier.
  • Unlike regular interface methods, default methods have implementation(method body).
  • We can have any number of default methods in an Interface.

Further if want to learn more on the default methods, you can visit Oracle official documentation.

close

Leave a Reply

Top