This article explains Default Interface Methods introduced in Java8 and how to use them in multiple inheritance scenarios.

Interface default methods

Prior to JDK 8, an interface could not contain any implementation. Interfaces contain only constants and method signatures.

Beginning JDK 8, it is possible to define default implementation for a method in an interface. These methods are called default methods.

A default method is declared using a keyword “default” and it contains a method body.

A default method is available to all implementing classes of the interface. If the implementation class wants to use it, it can use it or it can ignore the default implementation and create its own implementation.

Even though an interface can now define default methods, the interface must still be implemented by a class if an instance is to be created.

Here is an example of interface with a default method :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packagejava8;

publicinterfaceMyIF{

intadd(intx,inty);

//default method

defaultintmultiply(intx,inty){

returnx*y;

}

}

The above interface declares an abstract method add() and a default method multiply().

Let’s create a class implementing this interface. Note that, an implementing class is only required to implement the abstract method. The default method can be used as is unless the implementing class wants to change the behaviour.

Let’s create two interfaces InterfaceA and InterfaceB that provide the default method hello() and a class implementing both these interfaces.

Now, the implementing class extends default method behaviour from both interfaces. So, if the implementing class does not implement the hello() method, a compilation error will occur for duplicate method declaration.

Here is the code :

1

2

3

4

5

6

7

8

9

10

packagejava8;

publicinterfaceInterfaceA{

defaultvoidhello(){

System.out.println("Hello A");

}

}

1

2

3

4

5

6

7

8

9

10

11

packagejava8;

publicinterfaceInterfaceB{

defaultvoidhello(){

System.out.println("Hello B");

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packagejava8;

//Compile error for duplicate default method names

publicclassMultipleDefaultdemo implementsInterfaceB,InterfaceA{

publicstaticvoidmain(String[]args){

}

}

Scenario 2 : Class overrides the default method

If we provide implementation for hello() in MultipleDefaultdemo class, then the default method will be overridden and the class’s hello() method will be used.

It is possible to explicitly refer to a default implementation in an inherited interface using super keyword.

The general form for this is :

InterfaceName.super.DefaultMethodName();

So, we can access the default method hello() in InterfaceA and InterfaceB as follows :

InterfaceA.super.hello();

InterfaceB.super.hello();

Here is the complete example :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

packagejava8;

publicclassMultipleDefaultdemo implementsInterfaceB,InterfaceA{

publicstaticvoidmain(String[]args){

newMultipleDefaultdemo().hello();

}

publicvoidhello(){

System.out.println("Hello Class");

InterfaceA.super.hello();

InterfaceB.super.hello();

}

}

Running the above program will generate output :

Hello Class

Hello A

Hello B

Scenario 3 : One interface extends another with same default method

In cases where one interface extends another, with both defining a common default method, the inheriting interface’s version of the method takes precedence.

So, if InterfaceB extends InterfaceA, then InterfaceB’s version of method hello() will be used.

Here is the code for the same :

1

2

3

4

5

6

7

8

9

10

packagejava8;

publicinterfaceInterfaceA{

defaultvoidhello(){

System.out.println("Hello A");

}

}

1

2

3

4

5

6

7

8

9

10

11

packagejava8;

publicinterfaceInterfaceBextendsInterfaceA{

defaultvoidhello(){

System.out.println("Hello B");

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

packagejava8;

publicclassMultipleDefaultdemo implementsInterfaceB,InterfaceA{

publicstaticvoidmain(String[]args){

newMultipleDefaultdemo().hello();

}

}

Running this will produce output :

Hello B

Difference between Interface with Default method and Abstract class

When we add default method to an interface, it looks like an abstract class, but they are not the same.

An abstract class can have constructors, instance variables, concrete methods, but we can’t have instance variables or constructors in the interface.

An interface with single default method can be used to refer to a lambda expression, but an abstract class cannot be used to refer to lambda expressions.

Read more on the difference between Interface with Default method and Abstract class here :