Archive

Archive for May, 2016

Java 8 Default Methods

Java8-LogoInterfaces in Java always contained method declaration not their definitions (method body). There was no way of defining method body / definition in interfaces. This is because historically Java didn’t allow multiple inheritance of classes. It allowed multiple inheritance of interfaces as interface were nothing but method declaration. This solves the problem of ambiguity in multiple inheritance. Since Java 8 it is now possible to add method bodies in interfaces.

Java 8 has a new feature called Default Methods. It is now possible to add method bodies into interfaces!

package com.javainsider.java8.defaultmethods;

public interface DefaultMethod {
int addNumber(int num1, int num2);
default int multiplyNumber(int num1 , int num2){
return num1 * num2;
}
}

In above DefaultMethod interface we added a method multiplyNumber with actual method body.

Why we need Default Methods?

Why would one want to add methods into Interfaces? We’ll it is because interfaces are too tightly coupled with their implementation classes. i.e. it is not possible to add a method in interface without breaking the implementor class. Once you add a method in interface, all its implemented classes must declare method body of this new method.

Since Java 8, things started getting ugly. A new feature Lambda was introduce which is cool. However it is not possible to use this feature in existing Java libraries such as java.util package. If you add a single method in interface List, it breaks everything. You need to add its implementation in every class that implements List interface. Imagine in real world how many custom classes would change.

So for backward compatibility, Java 8 cleverly added Default Methods.

Virtual Extension Methods

It added a new concept Virtual extension methods, or as they are often called defender methods, can now be added to interfaces providing a default implementation of the declared behavior. So existing interfaces can be augmented without compromising backward compatibility by adding extension methods to the interface, whose declaration would contain instructions for finding the default implementation in the event that implementors do not provide a method body. A key characteristic of extension methods is that they are virtual methods just like other interface methods, but provide a default implementation in the event that the implementing class does not provide a method body.

Consider following example:

package com.javainsider.java8.defaultmethods;

public interface Person {

default void sayHello() {
System.out.println(“Hello…..”);
}

public void sayGoodby();

}

 

package com.javainsider.java8.defaultmethods;

public class JavaPerson implements Person {

@Override
public void sayGoodby() {
System.out.println(“Goodby Java person……”);
}
}

 

package com.javainsider.java8.defaultmethods;

public class TestJavaPerson {

public static void main(String[] args) {
JavaPerson javaPerson = new JavaPerson();

// calling sayHello method calls the method defined in interface
javaPerson.sayHello();

// calling sayGoodby- method calls the method implemented in JavapPerson
javaPerson.sayGoodby();
}

}

Output:

Hello……

Goodby Java person……

In above code we added a defender method sayHello() in Person interface. So it was ok for class JavaPersonto avoid declaring this methods body.

What about Multiple Inheritance?

Adding method definitions in interfaces can add ambiguity in multiple inheritance. isn’t it? Well, it does. However Java 8 handle this issue at Compile type. Consider below example:

package com.javainsider.java8.multipleinheritance;

public interface Person {

default void sayHello() {
System.out.println(“Hello…”);
}
}

 

package com.javainsider.java8.multipleinheritance;

public interface Female {
default void sayHello() {
System.out.println(“Hello Ms….”);
}
}

 

package com.javainsider.java8.multipleinheritance;

public interface Male {

default void sayHello() {
System.out.println(“Hello Mr….”);
}
}

 

package com.javainsider.java8.multipleinheritance;

public class Martin implements Person, Male{

@Override
public void sayHello() {
//Male.super.sayHello();
System.out.println(“Hello… I am Martin here….”);
}

}

It is also possible to explicitly call method from child class to parent interface. Consider in above example you want to call sayHello method from Male interface when Martin.sayHello is called. You can use super keyword to explicitly call the appropriate method or you can write your own implementation.

You can access the code from GIT repo:  https://github.com/javainsider/java8features

 

Happy Coding!

 

 

 

%d bloggers like this: