Java default method

Till Java 1.7 within an interface, we used to have only abstract methods. Abstract methods will have only a declaration but no definition. But from Java 1.8 we can define the methods within the interface and these are known as Java default methods. But what was the need?

CPU efficient methods

Java guys want to make our life easier hence they have written some Api’s which are very CPU efficient. Developers can make use of these API’s if needed and can reduce their custom code. One such API is Stream API using which we can do some aggregate functions like filter, map, limit, reduce, etc. With the new technologies coming into the market like BigData, artificial intelligence, and many more we need to do optimization on a large amount of data. We have to work on multiple sets of data and provide results quickly using the CPU effectively. This is known as parallelism.

Ex : Suppose we have to estimate the weather forecast for next month. Now data scientists will collect the data from the last few years and apply some algorithms to that data and reach a conclusion. This data can be in terabytes hence for executing an algorithm on such huge data sequentially will take hours to complete. So data scientists will split out the data into small sets and apply the algorithm on each set of data parallelly. Hence the activity will take only a few minutes to complete instead of few hours.

Note* The above-discussed functions are added as default methods in the Collection API.

Life before default methods

If we follow the old approach of the interface (i.e) the interface contains only abstract methods then the new CPU efficient methods which are added in Collection Interface have to be implemented by all the implementor classes like ArrayList, HashSet, etc. This is a very bad approach because it breaks the current system and we will get compilation issues. Also if we don’t need these new methods still we have to implement them which makes no sense. So to overcome this Java introduced a new feature called “default method” which will be backward compatible and these methods will have some default definition. We will try to understand it better with an example :

interface Addition {
  int add(int a, int b);
}

class A implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class B implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class C implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

public class Main {
  public static void main(String[] args) {
    Addition addition = new C();
    System.out.println(addition.add(5, 10));
  }
}

Output : 15

Suppose we add a new method “sum” as part of the Addition interface. Now all the implementing classes have to override that sum method else there will be a compilation error. This is not good for the existing applications because developers have to give some dummy implementation to the new methods even though they don’t need those new methods.

interface Addition {
  int add(int a, int b);
  int sum(int a, int b);
}

class A implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class B implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class C implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

public class Main {
  public static void main(String[] args) {
    Addition addition = new C();
    System.out.println(addition.add(5, 10));
  }
}

Output :

Main.java: error: A is not abstract and does not override abstract method sum(int,int) in Addition
class A implements Addition {
^
Main.java: error: B is not abstract and does not override abstract method sum(int,int) in Addition
class B implements Addition {
^
Main.java: error: C is not abstract and does not override abstract method sum(int,int) in Addition
class C implements Addition {
^
3 errors

To overcome the above issue default method was introduced. From Java 8 we can create the default method with some default definition within the interface. It is not necessary to override those methods in the implementation classes hence the existing application won’t break and provide backward compatibility.

Default method example

interface Addition {
  int add(int a, int b);
  default int sum(int a, int b) {
    return a + b;
  }
}

class A implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class B implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class C implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

public class Main {
  public static void main(String[] args) {
    Addition addition = new C();
    System.out.println("add method called : " + addition.add(5, 10));
    System.out.println("sum method called : " + addition.sum(5, 10));
  }
}

Output : add method called : 15
         sum method called : 15
		 

Overriding default methods

Suppose the implementing class wants a custom implementation for the default method then we can achieve it using overriding. We will try to understand with the below example :

interface Addition {
  int add(int a, int b);
  default int sum(int a, int b) {
    return a + b;
  }
}

class A implements Addition {
  public int add(int a, int b) {
    return a + b;
  }
}

class B implements Addition {
  public int add(int a, int b) {
    return a + b;
  }

  public int sum(int a, int b) {
    return 2 * a + 2 * b;
  }
}

public class Main {
  public static void main(String[] args) {
    Addition add = new A();
    System.out.println("class A add method called : " + add.add(5, 10));
    System.out.println("class A sum method called , default method gets called : " + add.sum(5, 10));

    Addition addition = new B();
    System.out.println("class B add method called : " + addition.add(5, 10));
    System.out.println("class B sum method called , doubled first/second parameters and added : " + addition.sum(5, 10));
  }
}

Output : 

class A add method called : 15
class A sum method called , default method gets called : 15
class B add method called : 15
class B sum method called , doubled first/second parameters and added : 30 

Multiple interfaces

Suppose there are 2 interfaces having a method with the same signature but different implementations. And a single class is implementing both the interfaces then what will be the output :

interface Addition {
  default int add(int a, int b) {
    return a + b;
  }
}

interface Sum {
  default int add(int a, int b) {
    return 2 * a + 2 * b;
  }
}

class A implements Addition, Sum {

}

public class Main {
  public static void main(String[] args) {
    Addition addition = new A();
    System.out.println("add method called : " + addition.add(5, 10));

  }
}

Output : Main.java: error: class A inherits unrelated defaults for add(int,int) from types Addition and Sum

It will be a compilation issue because our java compiler is confused about which default method should be used. We are having 2 solutions in this case :

Override a method

We will override add method in class A .

interface Addition {
  default int add(int a, int b) {
    return a + b;
  }
}

interface Sum {
  default int add(int a, int b) {
    return 2 * a + 2 * b;
  }
}

class A implements Addition, Sum {
  public int add(int a, int b) {
    return 3 * a + 3 * b;
  }
}

public class Main {
  public static void main(String[] args) {
    Sum addition = new A();
    System.out.println("add method called : " + addition.add(5, 10));

  }
}

Output : add method called : 45

Super keyword

We can call the default method of the required interface using the super keyword.

interface Addition {
  default int add(int a, int b) {
    return a + b;
  }
}

interface Sum {
  default int add(int a, int b) {
    return 2 * a + 2 * b;
  }
}

class A implements Addition, Sum {
  public int add(int a, int b) {
    return Sum.super.add(a, b);
  }
}

public class Main {
  public static void main(String[] args) {
    Addition addition = new A();
    System.out.println("add method called : " + addition.add(5, 10));

  }
}

Output : add method called : 30

Hope you did like this article. If you want to add anything extra please comment below and notify me if I have gone wrong anywhere. Also, you can write to me if you want to understand any other concept.

Leave a Comment