The diamond problem with default methods
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).