Monday, April 14, 2014

An insight of Functional Interfaces

Introduction

The recently launched JDK8, brought many exciting and noticeable changes in the SDK. One of those is functional interfaces or capability of adding implementation in interfaces. This article gives a brief about this feature.

Q1.  Can you briefly explain this new feature?
Java 8 allows interfaces to have default implementation for one or more methods. The implementer (abstract or concrete) classes may or may not override these default methods. Along with this, you can also have one or more static methods with implementation.
As example:
public interface TestDefaultMethod {
   
       void simpleMethod();
 
       default String newDefaultMethod() {
             String msg = "Hello. I am new default method on the Interfaces, introduced in Java 8.";
             System.out.println(msg);
             return msg;
       }      

       static String newStaticMethod(){
             String msg = "Hello. I am new static method on the Interfaces, introduced in Java 8.";
             System.out.println(msg);
             return msg;
       }
}

Q2.  Do I need to recompile the existing implementer classes, if I add new default method in Interface?
No. That is the whole idea and purpose of this feature. It is backward compatible with compiled code. You needn’t to change the implementer classes, if you add any default or static method in interface. This provides the power to roll out changes in Interface without impacting implementing classes.

Q3.  What all can I access from the default methods in Interfaces?
You can access all static variables, static methods and other default methods of the interface and its parents.

Q4.   What all can I access from the static methods in Interfaces?
You can access all static variables and other static methods of the interface and its parents.

Q5.  What about “Multiple Inheritance” introduced due to this. Suppose I’ve a class, implementing 2 interfaces with same default methods (same signature). What will happen in that case?
This is the same case as shown below.

This is kind of “Multiple Inheritance” introduced due to this feature. Here you will get a compiler error, saying “Duplicate default methods…”.
But note that if the implementing class overrides all common (conflicting) default methods, than this would work fine and, offcourse, implementation in class will be invoked.
See this example:
public interface InterfaceA { 

       default void newDefaultMethod() {
             String msg = "InterfaceA#newDefaultMethod method invoked";
             System.out.println(msg);         
       }
}

public interface InterfaceB { 

       default void newDefaultMethod() {
             String msg = "InterfaceB#newDefaultMethod method invoked";
             System.out.println(msg);                 
       }
}

//Compilation Error. Default method conflict.
public class TestConflict implements InterfaceA, InterfaceB{      

       public static void main(String[] args) {
             new TestConflict().newDefaultMethod();
       }
}

//This would work fine, as the class override the method.
public class TestConflict implements InterfaceA, InterfaceB{      

       public static void main(String[] args) {
             new TestConflict().newDefaultMethod();
       }      

       @Override
       public void newDefaultMethod() {
             String msg = "TestConflict#newDefaultMethod method invoked";
             System.out.println(msg);  
       }
}

Q6.  What about “Diamond Problem”? Imagine a situation where I’ve an interface with a default method. Now there is an abstract class implementing this interface and overrides the default method. Moreover, I’ve a concrete class, which extends the abstract class and also implements the interface directly. In this case, if someone calls the default method, which implementation (one in Interface or in Abstract class) will be invoked?
This scenario is shown below:

In this case, the implementation in Abstract class will be preferred.
Example:
public interface InterfaceA {

       default void newDefaultMethod() {
             String msg = "InterfaceA#newDefaultMethod method invoked";
             System.out.println(msg);            
       }
}

public abstract class AbstractImpl implements InterfaceA {

       @Override
       public void newDefaultMethod() {
             String msg = "AbstractImpl#newDefaultMethod method invoked";
             System.out.println(msg);       
       }
}

public class TestDiamond extends AbstractImpl implements InterfaceA {      

       public static void main(String[] args) {
             //Method in AbstractImpl will be called.
             new TestDiamond().newDefaultMethod();
       }
}

Q7.  What is your take on the semantic and theoretical view on functional interfaces?
For this, wait for my next blog “Impact of functional interfaces on Object Oriented Programming and Design” J