Default Methods, 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. Since in Java, one class can implement multiple interfaces and because there can be concrete methods in interfaces, the diamond problem has 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? Well, it's not but the doubt is genuine because interface with methods is similar to abstract class or in that any Class in Java.

In theory, it does look like that but in detail, you will find that Java designers have made sure that the diamond problem should not occur because of default methods on the interface from Java 8 onwards.

If you look closely, you will find that multiple inheritances of classes are not supported in Java 8, instead, the 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 the default methods with the same name.

We'll explore this concept with a proper code example in the coming section but let me tell you that this feature is so underrated yet it has made the biggest impact in terms of evolving JDK API.

Without default and static methods on an interface, it wasn't possible to add new methods on an interface and put the years of learning Java designer has after publishing JDK API.

Now, we have methods like putIfAbsent() on Map interface and comparing() on Comparator class which makes day to day coding in Java more effective. All this is possible because of default methods and static methods on the interface.

Btw, Java 8 is not just about default methods, it's full of useful features like lambda expressions, Stream API, new Date Time API and many minor API changes like join() method on String. If you are interested to learn those gems, I suggest you join What's New in Java 8 class on Pluaralsight. One of the short and sweet course to learn Java 8 in quick time.




An Example of Diamond Problem with Default Methods

Here is an example to explain that concept. As shown below, this code will not compile in Java 8, because of ambiguity in calling the 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


You can see that both Poet and Writer interface has a default method write() and when we have created a class Multitalented, which implements both Poet and Writer it gets the write() method from both super interface Poet and Writer.

Now, the problem is not that we have implemented two interfaces with default methods of the same name. The Actual problems come when we created an object of Multitalented class and called write() method on its object.

At this point of time, Compiler doesn't know that which write() method should call because of ambiguity and that result in the compiler error you have seen above.

Btw, if you are not familiar with how to interface and class works in Java and how compiler resolves a particular method call, I suggest you to first read a comprehensive Java course like The Complete Java MasterClass on Udemy. It's one of the best course and also very affordable. It's also most up-to-date and recently updated for Java 11.

Default Methods, Multiple Inheritance and Diamond Problem in Java 8



How to avoid Diamond Problem With Default Methods in Java 8

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 a compile-time error "inherits unrelated defaults".


Further Reading
The Complete Java MasterClass
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 Free Courses to learn Java 8 and Java 9 (courses)
  • 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 Optional in Java 8? (example)
  • Difference between abstract class and interface in Java 8? (answer)
  • Top 5 Online Courses to Master Java 8 Concepts (courses)

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.

P.S.: If you just want to learn more about new features in Java 8 then please see the course What's New in Java 8. It explains all the important features of Java 8 e.g. lambda expressions, streams, functional interfaces, Optional, new Date Time API and other miscellaneous changes.

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