We all know about the diamond problem regarding multiple inheritance -
A
/ \
B C
\ /
D
This problem describe an ambiguous situation for class D
. If class A
has a method and both/either of B
and/or C
override the method then which version of method does D
override?
Is this problem also applicable for interfaces in Java? If not, how do Java interfaces overcome this problem?
The diamond problem only applies to implementation inheritance (extends
in all versions of Java prior to Java 8). It doesn't apply to API inheritance (implements
in all versions of Java prior to Java 8).
Since interface methods with matching type signatures are compatible, there is no diamond problem if you inherit the same method signature twice: matching method signatures simply coalesce instead. (And if the type signatures aren't the same, then you don't have the diamond problem either.)
In Java 7 and below, the only way to inherit implementation code was via the extends
keyword, which restricts to at most one parent. Therefore there is no multiple implementation inheritance and the diamond problem does not exist.
Java 8 adds a new wrinkle because it allows interfaces to have implementation code. It still escapes the diamond problem by simply falling back to the previous behavior (no implementation inheritance) when you're implementing multiple interfaces with methods that have matching signatures.
To add to existing answers about Java8 multiple inheritance with interfaces (a.k.a. how Java still avoids the diamond problem):
There are three rules to follow:
A class always wins. Class's own method implementation takes priority over default methods in Interfaces.
If class doesn't have any: the most specific interface wins
- If above is not the case, inheriting class has to explicitly state which method implementation it's using (otherwise it won't compile)
Java overcomes this problem even though interfaces can have default implementations of methods, because the default implementation is either unambiguous (the one in class A
) or the situation is solved by some rule (when class B
or class C
overrides the implementation from class A
, see below).
When the supertypes of a class or interface provide multiple default methods with the same signature:
- Instance methods are preferred over interface default methods.
- Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
However, if two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods. In this case you could invoke any of the of the default implementations with the super keyword.
With default methods in interface introduced in Java 8, multiple inheritance related problem may arise, there are 3 scenarios -
1- If implementing class overrides the default method and provides its own functionality for the default method then the method of the class takes priority over the interface default methods.
2-When class implements both interfaces and both have the same default method, also the class is not overriding that method then the error will be thrown.
3-In case when an interface extends another interface and both have the same default method, the inheriting interface default method will take precedence.
read more about it here.
Java doesn't support multiple inheritance, so the diamond problem doesn't arise. If B & C are interfaces, then there is no implementation in the interfaces. Even if B & C override the method in interface A (cannot be a class), the methods will have same signature. There is no ambiguity regarding which implementation to use, because there is no implementation.
Interfaces having dummy declarations and they won't have implementations hence no ambiguity problem.
来源:https://stackoverflow.com/questions/29758213/multiple-inheritance-ambiguity-with-interface