The Diamond Head Problem in Java and why interfaces are almost always a good option for Data…
Hi, you must be wondering how this problem which used to occur mainly in C++ started coming in Java as well. Folks who are familiar with…
The Diamond Head Problem in Java and why interfaces are almost always a good option for Data Abstraction.

Hi, you must be wondering how this problem which used to occur mainly in C++ started coming in Java as well. Folks who are familiar with Java SE 7 or lower might never even had come through this issue. But others like me who have used Java SE 8 as well as coded in Kotlin might be knowing that with the changes made in Java 8, this problem has started occurring here as well albeit in a different form.
So, let me start with a quick intro to the problem at hand. C++ supports multiple inheritance. Lets focus on the lower part of the diamond. Lets have a class “Child” which inherits a property from “Father” and “Mother” classes.The code looks something like :

Child inherits roundFace behaviour/property from its parents.
This code will show an error in the IDE itself when you try to make a reference of the Child class as shown here :

IDE throws an error!
This classic problem of Diamond Head is easily solved by using virtual inheritance in C++.
Does this problem occur in Java as well? 😕 Well, Yes and No. Wait! What? 😐
Java doesn’t support multiple inheritance from classes by default. Also, in Java SE 7 and below, we can’t define any methods in Java interfaces. Implementing interfaces in Java can be seen as a class fulfilling contracts by implementing specific sets of rules declared in the contract (interface). Nope, implementation of multiple interfaces is NOT multiple inheritance (At least this was the case till Java SE 7).
Let’s see a case in Java SE 7 (Lets take a simple case of Dogs this time):
interface Bark {
void print();
}
interface Tail {
void print();
}
class Dog implements Bark,Tail {
@Override
void print(){
System.out.println("Oops, which interface's method do I use?");
}
}
This case might look like a Diamond Head problem but trust me it isn’t, as both the interfaces’ methods don’t have any definitions. The implementation is done by the concrete class Dog. Since, both the function signatures are the same, it doesn’t matter which interface’s method is implemented in the concrete class. We have a single implementation of the function and the compiler doesn’t get confused. Well that sounds good.
Now comes in Java SE 8 with its new features and its changes to the existing APIs. And one of its major changes to the interface was the addition of default methods to interfaces.
What is a default method? 😕 A) Default methods were introduced in Java to help maintain our legacy code in a better way. Earlier, if any new method had to be added to an existing interface, we also had to write its definition in the corresponding concrete class. But now we can allow interfaces to have implementations to methods without changing the structure of the class implementing it. You can say that default method implementation in interfaces from Java SE 8 onwards is similar to multiple inheritance as the default method is inherited by the class implementing it. Isn’t that great? Well it’s great especially for huge code bases but this default implementation gives rise to a major problem. Yes! The diamond head problem.
How? Let me show you. Let’s take the Dog use case.

The two interfaces now have a default implementation of the print method.
As you can see the two interfaces now have their methods already defined in it. So what happens now when we try to implement these two interfaces in the Dog class. Let’s code and see (Here, let’s assume that we want to use the default interface implementations and not class level overriden method.). This is how my Dog class would look like :

Dog class in Java. Oops! IDE already shows me an error here. However, we’ll still run and see if some error comes by.
On running the above program, I get an error in my terminal window :

Java compiler is confused 😖
Java is not sure which default implementation to use. Unlike C++, there is no “virtual” keyword in Java or concept of virtual inheritance in Java. Fortunately, Java does give us a way to resolve this disambiguity. We can use the super keyword preceded by the Interface name (the interface whose default implementation we want to run) and followed by the method name. Something like (I’ve refactored the code and separated the calling of class methods to make the code look clean.):

Specified which interface’s print() method to use
This gives me the output as :

Interface methods get called.
Thus Java gives us an elegant way to solve the Diamond Head problem for versions 8 and above when using interfaces with default implementation.
Now coming to the second question as to why we should almost always prefer interfaces for Data abstraction in place of abstract classes. Let’s see. Suppose you have an abstract class with a defined method, and an interface with default methods only. Which one would be a better option and why? Let’s see this in code :

Abstract class with defined method and interface with default method. This code works well and gives the desired output.
Sounds pretty cool. No problem in this, right? Method names are different and no conflict occurs. Ok, let’s see a similar use case when method signatures conflict :

Abstract classes and interfaces with the same method names.
Here we can see that neither the IDE, nor the compiler nor the Runtime throws any error as shown by the output :

However, you would notice that the compiler resolves to the class’s implementation by default and not the interface’s. This can be considered as ‘class wins’ rule. This helps resolve ambiguity issues and also maintain backward compatibility with versions below Java SE 8. Let’s say in your legacy code, you have a class which is extending a base class as well as implementing your interface. When you define a method with the same signature as that of the base class, the output of your legacy code doesn’t change and the class’s definition is used by default unless you specify the interface definition by using, <Interface name>.super.<method name>.
However, when you architect your own system, more often than not you wouldn’t want your base class definition but would definitely want to use your interface implementations (that too, implementations from not once interfaces but many). Once you extend a base class , you can’t extend any other class as Java doesn’t support multiple inheritance via the “extends” keyword. Its not a good design practice to have too many unnecessary or unrelated abstractions in your base class. Hence, we use interfaces, as Java does allow us to implement multiple interfaces and we can use an interface for a specific use case. This helps us in not only writing clean and structured code but also make it understandable. Separation of concerns help us in following Solid principles and make parts of our code decoupled from each other.
Apart from Java SE 8 and above, people who are working in Android development and especially have worked in Kotlin, will see that we can have method definitions in interfaces as well as in abstract classes. Then what’s the difference between the two then apart from syntax difference? 😕 What we can say in this case is that abstract classes can hold the state of an object and interfaces cannot. From a solution/abstract perspective its absolutely right, however, from a JVM perspective, this explanation is actually wrong. That’s a topic for another article where I will discuss how JVM resolves classes and objects internally and stores their meta information in the memory.
Till then, Happy Coding! 😄
메타데이터
- post_id
- f35ea4cd2a90
- slug
- the-diamond-head-problem-in-java-and-why-interfaces-are-almost-always-a-good-option-for-data-f35ea4cd2a90
- url
- https://medium.com/@gangulysourik/the-diamond-head-problem-in-java-and-why-interfaces-are-almost-always-a-good-option-for-data-f35ea4cd2a90
- canonical_url
- https://medium.com/@gangulysourik/the-diamond-head-problem-in-java-and-why-interfaces-are-almost-always-a-good-option-for-data-f35ea4cd2a90
- author_url
- https://medium.com/@gangulysourik
- status
- ok
- fetched_at
- 2026-08-09 01:15:27