Interface in Java 8: Introduction of default and static methods in Interfaces

In the traditional form of Interfaces, we could only define abstract methods(containing no body) in the interfaces. With the introduction of JDK 8, we can now define default methods and static methods.

Let’s see a brief introduction of the interface before we move on to the default and static methods in an interface.

Interfaces in Java

The interface is an abstract type that specifies the behavior of a class that implements it. An interface is used mostly to specify what a class must do and not how it does it. They are similar to classes in syntax but do not contain instance variables and they only define abstract methods(i.e., methods without body). Any number of classes can implement an interface and also a class can implement any number of interfaces.The class must provide an implementation for all the methods of the interface it implements. Interfaces can be declared by using the keyword ‘interface‘ much the same way as a class :

modifier interface InterfaceName{
    //body
}

The power of interface is realized at the time of dynamic method resolution during run-time. When a method is called from one class to another, the presence of both the classes is required to check that the method signatures match. This attributes to a very static and non-extensible classing environment. This problem is resolved with the use of interfaces as it disconnects the definition of the method or methods from the inheritance hierarchy.

Prior to JDK 8, interfaces could only define what and not the how. But this has been changed in JDK 8 where the interfaces are capable of specifying a default implementation of its methods. We shall see more details on these implementations in the following subsections.


Default Methods

Rather than being abstract, the methods defined in an interface can now have a default implementation for the method, i.e. have a body. Default methods were called extension methods during its development. They are also referred to as Virtual extension methods or Defender methods. Default methods are implemented by writing the default keyword at the beginning of the method definition. All methods inside an interface(including default methods) are implicitly public so the programmer can skip the public modifier. An example of a default method is:

default String getNum(int n) {
    return "The number is: " + n;
}

 About Default Methods

  • Default methods help us to get binary compatibility for older versions of the interfaces.
  • The default method avoids breaking of existing code. We know that all the methods that are defined by an interface must have an implementation. If another method was added to a pre-existing interface then it would break the existing code as no implementation would be found for the new method. Using default method solves this problem as it has it’s own implementation even if the code does not provide any for the method.
  • It helps the utility classes to support Lambda Expressions.
  • A default method cannot override the method of the java.lang.Object class because Object is the base of all classes and it will always be used despite the default implementation.

Multiple Inheritance Issues for Default Methods

Java does not support multiple inheritances of classes but implementing multiple interfaces is one of the important aspects of Java. For the traditional interfaces, that had abstract methods, providing an implementation of the methods was compulsory. But with the introduction of default methods, the user can liberally provide an implementation of the methods he/she requires. That raises the Diamond Problem where the compiler cannot decide which superclass method to use. For example:

interface I1 {
    default void display(String str){
        System.out.println(str);
    }
}

interface I2 {
    default void display(String s){
        System.out.println(s);
   }
}

In such a case it becomes difficult for the compiler to decide which method to go for. To this problem, there are two solutions:

  • To override the method in the subclass:
public class A implements I1, I2 {
    default void display(String strg) {
        System.out.println(strg);
   }
}
  • To explicitly specify the interface that the needs to be overridden using the keyword super.
public class A implements I1, I2 {
 
    default void display(String strg) {
        I1.super.display(strg);
    }
}

Program to show the use of default method

/**
 *This program shows the use of a default method in an interface
 *The following interface I1 contains an abstract method and a default method.
 */
 
package com.codingeek.java8.DefaultStaticInterfaceMethods;

public interface I1 {

    //a traditional abstract method declaration inside an interface
    void printNum(int n);
    
    //a default method inside the interface
    default void printString() {
        System.out.println("Inside the default method.");
    }
}

/**
 * This class provides implementation for the abstract method of the interface I1.
 */

public class DefaultMethodExample implements I1 {
    
    //providing an implementation for the abstract method printNum().
    //implementation for printString() need not be provided.
    public void printNum(int n) {
        System.out.println("The number is:" + n);
    }
}

//calling both the default and the abstract method.
public class DefaultMethodDemo {
    
    public static void main(String args[]) {
        DefaultMethodExample ob = new DefaultMethodExample();
        
        //Use the object created to call the method printNum()
        ob.printNum(10);
        
        //Use the object to call the method printString()
        ob.printString();
    }
}

Output:-
The number is:10
Inside the default method.

Static Methods in an Interface

Java 8 also introduced static methods in interfaces. Unlike default methods, static methods are not overridden in order to avoid poor implementation of the method. If we use the @Override annotation to override the static method an error occurs. Static methods can be called independently of any object, i.e. no instance is required to call this method. It can be simply called by specifying the name of the interface followed by a dot(.) and the name of the method as shown below:

InterfaceName.staticMethodName;

Program to show the use of Static methods

/**
 *This program shows the use of a static method in an interface
 *The following interface I1 contains an abstract method and a static method.
 */
 
package com.codingeek.java8.DefaultStaticInterfaceMethods;

public interface I1 {

    //a traditional abstract method declaration inside an interface
    void printNum(int n);
    
    //a static method inside the interface
    static void printString() {
        System.out.println("Inside the static method.");
    }
}

/**
 * This class provides implementation for the abstract method of the interface I1.
 */

public class StaticMethodExample implements I1 {
    
    //providing an implementation for the abstract method printNum().
    //implementation for printString() need not be provided.
    public void printNum(int n) {
        System.out.println("The number is:" + n);
    }
}

//calling both the static and the abstract method.
public class StaticMethodDemo {
    
    public static void main(String args[]) {
        StaticMethodExample ob = new StaticMethodExample();
        
        //Use the object created to call the method printNum()
        ob.printNum(10);
        
        //for a static method we can directly call the method without the creation of an instance.
        I1.printString();
    }
}

Output:-
The number is:10
Inside the static method.

An investment in knowledge always pays the best interest. Hope you like the tutorial. Do come back for more because learning paves way for a better understanding.

Do not forget to share and Subscribe.

Happy coding!! 🙂

Recommended -