Diamond Problem with Default Methods
Fast recall
Quick revision
Core answer
InterfaceName.super.methodName().Understanding of the diamond problem with default methods and Java's conflict resolution rules.
Saying every same-signature pair is ambiguous and missing Java's class-wins and more-specific-interface rules.
State all three resolution rules, then demonstrate `InterfaceName.super.method()` for two unrelated direct superinterfaces.
Interview-ready guide
Interview answer
When a class would inherit the same default signature from two unrelated interfaces, Java reports a compile-time conflict and the class must override the method. In that override it can choose a direct superinterface with Notifier.super.send(), deliberately call both, or provide a new body.
There are two precedence rules to state first. A concrete method from a class wins over an interface default. If one interface is more specific because it extends the other, its default wins. Therefore, the error is not caused by every duplicate signature; it occurs when unrelated defaults remain with no more-specific choice. The order of names in the implements clause never decides it.
Diamond Problem with Default Methods
Direct Answer
If the two defaults come from unrelated interfaces, the implementing class gets a compile-time conflict and must override the method. A concrete class method wins over an interface default, and a more specific subinterface default wins over its parent. In an explicit override, the class may call a direct superinterface default with InterfaceName.super.methodName().
Code Example
interface Notifier {
default void send(String message) {
System.out.println("Notifier: " + message);
}
}
interface Logger {
default void send(String message) {
System.out.println("Logger: " + message);
}
}
// This class MUST resolve the conflict
class AlertSystem implements Notifier, Logger {
@Override
public void send(String message) {
// Option 1: Choose one parent's implementation
Notifier.super.send(message);
// Option 2: Combine both behaviors
// Notifier.super.send(message);
// Logger.super.send(message);
// Option 3: Provide completely new implementation
// System.out.println("Alert: " + message);
}
}
// Usage
var alert = new AlertSystem();
alert.send("System overload"); // Output: Notifier: System overload
// Without the override, this class won't compile:
// error: class AlertSystem inherits unrelated defaults for send(String)
Common Mistakes & Pitfalls
- Saying every pair is ambiguous: a class method wins, and a more specific subinterface default wins. Only unrelated surviving defaults require an override.
- Choosing by declaration order: the order of interfaces in the
implementsclause does not resolve unrelated defaults. - Using the wrong
superform: inside the override, call an eligible direct superinterface withNotifier.super.send(), not plainsuper.send(). - Calling both defaults automatically: combining two effects may duplicate work; choose behavior from the class contract.
Check your understanding
Answer these without looking back at the article.
- What are the three rules for resolving default method conflicts?
- What if a class extends a class AND implements an interface with the same default method?
- What is the diamond problem in multiple inheritance?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.