Default Methods in Interface, Multiple Inheritance and Diamond Problem in Java 8

Ever since Java 8 introduced default and static methods in JDK 8, it's become possible to define non-abstract methods in interfaces and since in Java one class can implement multiple interfaces and because there can be concrete methods in interfaces, the diamond problem surfaced again. What will happen if two interface has methods o the same name and a Java class inherit from it? Many Java programmer also asks me the question that, is Java 8 is also supporting multiple inheritances of classes, as it seems because interface with methods is similar to abstract class or in that any class. Well, it’s not.


Multiple inheritances of classes is not supported in Java 8, instead compiler will do additional checks to avoid ambiguity in calling default methods and Diamond problem, which could come if a class implements two interface which contains same default methods as shown in the following example, it will not compile in Java 8, because of ambiguity in calling default method write() from a class, which extends both Poet and Writer interface.

interface Poet {
    default void write() {
        System.out.println("Poet's default method");
    }
}

interface Writer {
    default void write() {
        System.out.println("Writer's default method");
    }
}

public class Multitalented implements Poet, Writer{
   
    public static void main(String args[]){
        Multitalented john = new Multitalented();
        john.write();  // which write method to call, from Poet
                       // or, from Writer
    }
}

Output:
Compile Time Error : class Multitalented inherits unrelated defaults for write() from types Poet and Writer



In order to solve this error, you need to override the write() method in your implementation class i.e. class Multitalented here, this will remove the ambiguity, making the compiler happy enough to compile this class.

public class Multitalented implements Poet, Writer{
   
    @Override
    public void write(){
        System.out.println("Writing stories now days");
    }
   
    public static void main(String args[]){
        Multitalented john = new Multitalented();
        john.write();  // This will call Multitalented#write() method
    }
}
Output:
Writing stories now days

So until you don't create ambiguity by using default methods on interfaces, you are fine to use it. If it creates ambiguity, the compiler will alert you by throwing compile time error "inherits unrelated defaults".


Further Reading
What's New in Java 8
Java SE 8 for Really Impatient
From Collections to Streams in Java 8 Using Lambda Expressions


Related Java 8 Tutorials
If you are interested in learning more about new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8:
  • 5 Books to Learn Java 8 from Scratch (books)
  • How to join String in Java 8 (example)
  • How to use filter() method in Java 8 (tutorial)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • How to use Stream class in Java 8 (tutorial)
  • How to convert List to Map in Java 8 (solution)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • How to use peek() method in Java 8 (example)
  • How to sort the map by keys in Java 8? (example)
  • How to sort the may by values in Java 8? (example)
  • 10 examples of Optionals in Java 8? (example)
  • Difference between abstract class and interface in Java 8? (answer)

Thanks for reading this article so far. If you like this article then please share with your friends and colleagues. If you have any question or feedback then please drop a comment.

1 comment:

  1. You have to remove one interface from the successful example otherwise it gives you compilation error like below

    "Default methods are allowed only in interfaces with source level 1.8 or greater."

    ReplyDelete