Java 8 : Interface Changes

Till java 7 we could have only method declarations in the interfaces.  It was virtually impossible to change an interface once published. Any change e.g. addition of a new method would have broken all clients. Java 8 now allows you to add non-abstract method implementations to interfaces by utilizing the default and static keyword.

Interface Default Method

For creating a default method in the interface, we need to use “default” keyword with the method signature.


public interface Interface1 {
    
    //regular method declaration
    void method1();
    
    //default method with a body
     default String method2(){        
        return "Method 2 default implementation";
    }

}

 

Now when a class will implement Interface1, it is not mandatory to provide implementation for default methods.


public class TestClient1 implements Interface1 {

    @Override
    public void method1() {
        // TODO Auto-generated method stub
    }

}

Important points on default methods:

  • This feature can only be compiled with jdk 8.
  • You are free to define any number of default methods in your interface.
  • You are allowed to override this method when necessary, and you can even re-declare it as an abstract method in an abstract class, forcing it to be implemented in concrete subclasses.
  • If a class implements 2 interfaces say Interface1 and Interface 2 having a default method with the same signature, it will create a ambiguity, hence its not allowed. Similarly, a interface cannot extend 2 or more interfaces for the similar reason.
  • You cannot use default methods to override any of the non-final methods in the java.lang.Object class. Following will give a compile time error.
    public interface Interface3 {   
        //A default method cannot override a method from java.lang.Object
        default String toString(){       
        }   
    }
    

    and of course final method cannot be overririden 🙂

One of the major reason for introducing default methods is to enhance the Collections API in Java 8 to support lambda expressions. One of the most popular one is forEach() method of Iterable interface. Best way to remember default method is to remember problem of using putIfAbsent() method ofConcurrentMap from JDK 1.7, which was not present in Map. It was not possible to write methods which can directly operate on Map interface because any time if a Map interface points to aConcurrentMapobject, you need to cast intoConcurrentMapjust for sake of using putIfAbsent() method. With extension methods, now JDK 8’sjava.util.Map interface has got its own putIfAbsent() method.

After introducing Default Method, it seems that interfaces and abstract classes are same. However, they are still different concept in Java 8. Abstract class can define constructor. They are more structured and can have a state associated with them. While in contrast, default method can be implemented only in the terms of invoking other interface methods, with no reference to a particular implementation’s state.

Interface static methods

Static methods are similar to default methods except that we can’t override them in the implementation classes. The static method is still part of the interface and not part of the implementing class.


package mynotes.java8.features;

interface A
{
static String method1()
{
return "Static method from interface";
}
}

class X implements A
{
}

public class TestInterfaceStatic
{
public static void main(String[] args)
{
A.method1();
//X.method1(); // won't compile
}
}

Again, here also, we cannot do hide methods of object class. It will throw a compile time error as “This static method cannot hide the instance method from Object”.

Functional Interfaces

The Java API has many one-method interfaces such as Runnable, Callable, Comparator, ActionListener and others. They can be implemented and instantiated using anonymous class syntax. These interfaces are also called Single Abstract Method interfaces (SAM Interfaces).  With Java 8 the same concept of SAM interfaces is recreated and are called Functional interfaces. Java 8 introduces an annotation – @FunctionalInterface too, which can be used for compiler level errors when the interface you have annotated violates the contracts of Functional Interface.


@FunctionalInterface
public interface SimpleSAMinterface {

public void method1();

}

If you try to add another abstract method, it will throw an error.

FunctionalINterfaceError

Ofcourse you can remove the annotation and then this would be like any other interface, but not a SAM interface which can only have a one abstract method.

Important points on SAM Interfaces:

  • Only one abstract method is allowed in any functional interface.
  • A functional interface is valid even if the @FunctionalInterface annotation would be omitted. It is only for informing the compiler to enforce single abstract method inside interface.
  • You can add many defaults methods to your SAM interfaces, since they have a implementation body.
  • Similary, you can also declare the abstract methods from the java.lang.Object class,  and it will still be valid since the Object class has an implementation.
    @FunctionalInterface
    public interface SimpleSAMinterface {
    
    public void method1();
    //Overriding the method from object class
    public String toString();
    
    }
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: