Memra

The diamond problem with default methods

◈ 4 cards

Two interfaces giving the same default method forces the class to resolve the conflict.

When defaults collide

If a class implements two interfaces that both provide a default method with the same signature, the class must override that method — otherwise the compiler reports an ambiguity error:

public interface A {
    default String greet() { return "Hello from A"; }
}

public interface B {
    default String greet() { return "Hello from B"; }
}

public class C implements A, B {
    // must override — the compiler cannot choose A or B
    @Override
    public String greet() {
        return A.super.greet();  // explicitly delegate to A's version
    }
}

Calling a specific parent default: use Interface.super.method() — the only place this syntax is valid.

Class always wins

If a class (not an interface) provides a concrete method with the same signature, that class method always wins over any interface default:

public class Base {
    public String greet() { return "Hello from Base"; }
}

public class D extends Base implements A {
    // Base.greet() wins — no override required, no ambiguity
}

Resolution priority: class/superclass concrete method > interface default method > ambiguity error (when two defaults tie without a class winner).

implementsimplementsinterface Adefault greet()interface Bdefault greet()class Cmust overrideambiguous until C overrides
Two defaults with one signature and no class in between: C will not compile until it overrides greet(), after which it may delegate with A.super.greet().
extendsimplementsclass Baseconcrete greet()interface Adefault greet()class Dinherits Base.greet()the class wins
The class hierarchy is consulted first, so an inherited concrete method always beats an interface default. D compiles untouched — no override required.
NORMAL ~/memra/learn/java-from-zero/diamond-problem utf-8 LF