11 Java - Interfaces (Latest Versions)

1. Default Method (Java 8)

Issue

  • Before Java8, Interface can have only Abstract method. And all child classes has to provide abstract method implementation.
public interface Bird{
    public void canFly();
}
public class Eagle implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }
}
public class Sparrow implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }
}

Any new method added in interface means need to change in all its implementation

public interface Bird{
    public void canFly();
    public int getMinimumFlyHeight();
}
public class Eagle implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }

    @Override
    public int getMinimumFlyHeight(){
        return 100;
    }
}
public class Sparrow implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }

    @Override
    public int getMinimumFlyHeight(){
        return 100;
    }
}

Fix using Default Method

public interface Bird{
    public void canFly();

    default int getMinimumFlyHeight(){
        return 100;
    }
}
public class Eagle implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }
}
public class Sparrow implements Bird{
    @Override
    public void canFly(){
        // Eagle fly implementation
    }
}

Usage in Main

public class Main {
    public static void main(String args[]){
        Eagle eagleobj = new Eagle();
        eagleObj.getMinimumFlyHeight();
    }
}

Why Default method was introduced?

  • To add functionality in existing Legacy Interface we need to use Default method. Example Stream() method in Collection.

Default and Multiple Inheritance, how to Handle?

Diamond problem with 2 inheritance

public interface Bird{
    default boolean canBreathe(){
        return true;
    }
}

public interface LivingThing{
    default boolean canBreathe(){
        return true;
    }
}

Error

public class Eagle implements Bird, LivingThing{
}

Fix

public class Eagle implements Bird, LivingThing{
    public boolean canBreathe(){
        return true;
    }
}

How to extend interface, that contains Default Method?

1st Way

public interface LivingThing{
    default boolean canBreathe(){
        return true;
    }
}
public interface Bird extends LivingThing{
}
public class Eagle implements Bird {
}

usage

public class Main {
    public static void main(String args[]){
        Eagle eagleobj = new Eagle();
        eagleObj.canBreathe();
    }
}

2nd Way

public interface LivingThing{
    default boolean canBreathe(){
        return true;
    }
}

Child Interface - Made it to abstract

public interface Bird extends LivingThing{
    default boolean canBreathe();
}

Not Possible: Error

public class Eagle implements Bird {
}

Fix

public class Eagle implements Bird {
    @Override
    public boolean canBreathe(){
        return true;
    }
}

3rd Way

public interface LivingThing{
    default boolean canBreathe(){
        return true;
    }
}
public interface Bird extends LivingThing{
    default boolean canBreathe(){
        boolean canBreatheOrNot = LivingThing.super.canBreathe();
        // do something else
        return canBreatheOrNot;
    }
}
public class Eagle implements Bird {
}

2. Static Method (Java8)

  • We can provide the implementation of the method in interface.

  • But it cannot be overridden by classes which implement the interface.

  • We can access it using interface name itself.

  • Its by default public.

public interface Bird {
    static boolean canBreathe(){
        return true;
    }
}

public class Eagle implements Bird {

    public void digestiveSystemTestMethod(){
        if(Bird.canBreathe()){
            // do something 
        }
    }
}

if you try to override it,

it will just be treated as new method in Eagle class

public class Eagle implements Bird {

    public boolean canBreathe(){
        System.out.println("in interface);
        return true;
    }
}

If you try to add @ override annotation

It will throw compilation error

public class Eagle implements Bird {
    @override
    public boolean canBreathe(){
        System.out.println("in interface);
        return true;
    }
}

3. Private Method and Private Static method (Java 9)

  • We can provide the implemenation of method but as a private access modifier in interface.

  • It brings more readability of the code. For example if multiple default method share some code, that this help.

  • It can be defined as static and non-static.

  • From static method, we can call only private static interface method.

  • Private static method, can be called from both static and non static method.

  • Private interface method can not be abstract. Means we have to provide the definition.

  • It can be used inside of the particular interface only. No other child classes/ interfaces can call the private methods.

public interface Bird {
    void canFly();

    public default void minimumFlyingHeight(){
        myStaticPublicMethod(); //Calling static method
        myStaticPrivateMethod(); //calling private static method
        myPrivateMethod(); //Calling private method
    }

    private void myPrivateMethod(){

    }

    static void myStaticPublicMethod(){
        myStaticPrivateMethod(); // from static we can call other static method only
    }

    private static void myStaticPrivateMethod() {
        //Private method implementation
    }
}