Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?
Ex:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
@Override
public int f() { // from which interface A or B
return 0;
}
}
As far as the compiler is concerned, those two methods are identical. There will be one implementation of both.
This isn't a problem if the two methods are effectively identical, in that they should have the same implementation. If they are contractually different (as per the documentation for each interface), you'll be in trouble.
Try implementing the interface as anonymous.
There is nothing to identify. Interfaces only proscribe a method name and signature. If both interfaces have a method of exactly the same name and signature, the implementing class can implement both interface methods with a single concrete method.
However, if the semantic contracts of the two interface method are contradicting, you've pretty much lost; you cannot implement both interfaces in a single class then.
Well if they are both the same it doesn't matter. It implements both of them with a single concrete method per interface method.
This was marked as a duplicate to this question https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
You need Java 8 to get a multiple inheritance problem, but it is still not a diamon problem as such.
As JB Nizet comments you can fix this my overriding.
However, you don't have a problem with
If a type implements two interfaces, and each
interface
define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inheritedinterface
methods, but also aninterface
and a superclass
method, or even just conflicts due to type erasure of generics.Compatibility example
Here's an example where you have an
interface Gift
, which has apresent()
method (as in, presenting gifts), and also aninterface Guest
, which also has apresent()
method (as in, the guest is present and not absent).Presentable johnny
is both aGift
and aGuest
.The above snippet compiles and runs.
Note that there is only one
@Override
necessary!!!. This is becauseGift.present()
andGuest.present()
are "@Override
-equivalent" (JLS 8.4.2).Thus,
johnny
only has one implementation ofpresent()
, and it doesn't matter how you treatjohnny
, whether as aGift
or as aGuest
, there is only one method to invoke.Incompatibility example
Here's an example where the two inherited methods are NOT
@Override
-equivalent:This further reiterates that inheriting members from an
interface
must obey the general rule of member declarations. Here we haveGift
andGuest
definepresent()
with incompatible return types: onevoid
the otherboolean
. For the same reason that you can't anvoid present()
and aboolean present()
in one type, this example results in a compilation error.Summary
You can inherit methods that are
@Override
-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE@Override
-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.The compiler does not have to identify which method is for which interface, because once they are determined to be
@Override
-equivalent, they're the same method.Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
References