The diamond problem occurs in multiple inheritance when a class inherits from two classes that have the same method, creating ambiguity. Java avoids this by:
- Not allowing multiple inheritance of classes (a class can extend only one class)
- Allowing multiple inheritance of interfaces (a class can implement many interfaces)
Why Interfaces Solve the Diamond Problem
- Interfaces provide method declarations without implementations (before Java 8).
- Even with default methods (Java 8+), conflicts are resolved explicitly by the implementing class.
Example: Diamond Problem in Classes (Not Allowed)
class A { void show() { System.out.println("A"); } }
class B extends A { void show() { System.out.println("B"); } }
class C extends A { void show() { System.out.println("C"); } }
// ERROR: Java doesn't allow this!
// class D extends B, C { }
// Which show() should D inherit? B's or C's? (Ambiguity → Diamond Problem)
Solution Using Interfaces
Case 1: No Default Methods (Before Java 8)
interface A { void show(); } // Only declaration
interface B extends A { void show(); }
interface C extends A { void show(); }
class D implements B, C {
@Override
public void show() { // Must implement (no ambiguity)
System.out.println("D's implementation");
}
}
✅ No conflict because the implementing class must provide its own implementation.
Case 2: Default Methods (Java 8+)
If two interfaces provide default implementations, the class must override the method to resolve ambiguity:
interface A {
default void show() { System.out.println("A"); }
}
interface B extends A {
default void show() { System.out.println("B"); }
}
interface C extends A {
default void show() { System.out.println("C"); }
}
class D implements B, C {
@Override
public void show() { // Must override to resolve conflict
System.out.println("D resolves the conflict");
// Can explicitly choose one:
B.super.show(); // Calls B's version
}
}
✅ Solution: The implementing class must override the conflicting method.
Key Takeaways
Scenario | Resolution |
---|---|
Two interfaces with abstract methods | Class must implement the method. |
Two interfaces with default methods | Class must override and choose one (or provide new logic). |
One abstract + one default method | Default method is ignored; class must implement the abstract method. |
Why This Works
- Interfaces do not have state (no fields), so no risk of conflicting data.
- The implementing class has full control over method resolution.
Conclusion
Java avoids the diamond problem by:
- Banning multiple class inheritance.
- Forcing interfaces to resolve conflicts explicitly.
This keeps code clean and predictable while allowing flexibility. 🚀