The default method in Java8

  • 2020-04-01 03:42:42
  • OfStack

Java 8 adds the default method, which adds new features to the interface without affecting the interface's implementation class. Let's illustrate this point with an example.


public class MyClass implements InterfaceA {
 public static void main(String[] args){
 }
 
 @Override
 public void saySomething() {
  // TODO Auto-generated method stub
 }
} interface InterfaceA{
 public void saySomething();
}

The code above shows that the MyClass class implements the saySomething() method of the InterfacesA interface. Now we add a sayHi() method to the InterfacesA interface. By doing this, the MyClass class will not compile unless we provide an implementation of sayHi().

The Default method is useful because the implementation class does not need to provide an implementation of the method by prefixing the access modifier of the method defined by the interface with the keyword Default. Such as:


public class MyClass implements InterfaceA {
 public static void main(String[] args){
 }
 
 @Override
 public void saySomething() {
  // TODO Auto-generated method stub
 }
} interface InterfaceA{
 public void saySomething();
 default public void sayHi(){
  System.out.println("Hi");
 }
}

Note that we must provide all implementations of the default method. Therefore, the default method makes our code more flexible and allows us to write method implementations in the interface. The method implemented will be implemented as the default method.
So what if there are conflicts between multiple interfaces?

Because Java classes can implement multiple interfaces, it is possible for two or more interfaces to have a default interface method with the same name, causing a conflict. Because the Java virtual machine is running, it is not clear which default method you want to use. This causes a compilation error.

Let's look at the following example.


public class MyClass implements InterfaceA, InterfaceB {
 public static void main(String[] args){
  MyClass mc = new MyClass();
  mc.sayHi();
 }
 
 @Override
 public void saySomething() {
  // TODO Auto-generated method stub
 }
} interface InterfaceA{
 public void saySomething();
 default public void sayHi(){
  System.out.println("Hi from InterfaceA");
 }
} interface InterfaceB{
 default public void sayHi(){
  System.out.println("Hi from InterfaceB");
 }
}

It does not compile, it will report the following error:
"Duplicate default methods named sayHi with the parameters () and () are inherited from the types of InterfaceB and InterfaceA."
Unless the sayHi() method is overridden in the MyClass class:


public class MyClass implements InterfaceA, InterfaceB {
 public static void main(String[] args){
  MyClass mc = new MyClass();
  mc.sayHi();
 }
 
 @Override
 public void saySomething() {
  // TODO Auto-generated method stub
 }
 
 @Override
 public void sayHi(){
  System.out.println("implemetation of sayHi() in MyClass");
 }
} interface InterfaceA{
 public void saySomething();
 default public void sayHi(){
  System.out.println("Hi from InterfaceA");
 }
} interface InterfaceB{
 default public void sayHi(){
  System.out.println("Hi from InterfaceB");
 }
}

If we want to specify which interface's sayHi() method to call, we can do this:


public class MyClass implements InterfaceA, InterfaceB {
 public static void main(String[] args){
  MyClass mc = new MyClass();
  mc.sayHi();
 }
 
 @Override
 public void saySomething() {
  // TODO Auto-generated method stub
 }
 
 @Override
 public void sayHi(){
  InterfaceA.super.sayHi();
 }
} interface InterfaceA{
 public void saySomething();
 default public void sayHi(){
  System.out.println("Hi from InterfaceA");
 }
} interface InterfaceB{
 default public void sayHi(){
  System.out.println("Hi from InterfaceB");
 }
}

Is the answer simple?


Related articles: