Why do some languages restrict multiple inheritance, and what is the diamond problem?
Because a class carries state, and two parents can both contribute members with the same name. When that happens, the language has to decide which one the subclass gets, and any answer is either arbitrary or needs a rule the programmer has to learn. The diamond problem is the classic shape of this trouble: a class inherits from two paths that meet at a common ancestor, and the shared ancestor's members arrive twice.
public class Main {
public static void main(String[] args) {
Printable p = new LaserPrinter();
System.out.println(p.describe());
System.out.println(p.source());
}
}
interface Printable {
default String source() { return "printable"; }
default String describe() { return "uses " + source(); }
}
interface Duplexable {
default String source() { return "duplexable"; }
}
class LaserPrinter implements Printable, Duplexable {
public String source() { return Printable.super.source(); }
}The example shows the conflict in miniature. Both interfaces supply a default source method, so a class implementing both would have two candidates for it. Java refuses to choose silently. The class has to say which one it wants, and the qualified form Printable.super.source() is the explicit syntax for that. If it had not said, the code would not compile.
The output shows the resolved behaviour: the printer reports that it uses printable, and asking for the source directly gives the same answer. The class had to resolve the conflict itself, and the qualified call names the winner explicitly.
The design principle behind the restriction is that ambiguity should be a compile error rather than a runtime surprise. Java handles this by separating the two kinds of inheritance. State comes from one class parent, so there is never a question about which inherited field you get. Behaviour can come from several interfaces, and when two of them supply the same default method the compiler forces you to resolve it explicitly.