views:

342

answers:

6

Here's an example using multiple interface inheritance in Java and there's an issue.

Note that I fully know why there's an issue and this is not the point of my question. The question is about how you name this particular multiple interface inheritance ambiguity, if there's a name for it.

For example, in C++, the ambiguity that arises when you use multiple implementation inheritance and cannot determine which overridden method to use is called the "diamond problem":

http://en.wikipedia.org/wiki/Diamond_problem

Now once again, I know this is not the same problem here: that's not the point. The point is that a name has been coined in that previous case.

And I'd like to know if a name exists for the issue I'm about to describe.

Here's an example of another kind of multiple inheritance, where one interface inherits from two other interfaces that have an incompatible method return type:

interface A {
  void a();
  Integer c();
}

interface B {
  void b();
  Long c();
}

interface MI extends A, B {...}

(notice multiple interface inheritance at work using the 'extends' keyword)

You cannot do that, because:

types A and B are incompatible; both define c() but with unrelated return type

Has a name been coined to describe that situation?

A: 

I don't think a name has been defined because interfaces in Java cannot have method implementation, the problem is therefore avoided since there is always only one implementation to a specific method and hence no ambiguity will arise.

Have I missed the point or are you talking about the 'c' variable?

zinc
Yes. you missed the point. read the question again.
shoosh
...and `c` isn't a variable, not even a field... it's a method.
Lucero
@zinc: "no ambiguity"? In the code sample from the question there is an ambiguity: What must the implementation of `MI.c()` return? Integer or Long?
Carlos Heuberger
+1  A: 

I'd hesitate to call this a multiple inheritance issue, because interfaces merely describe well, interface--a set of methods an implementing class must define--rather than any implementation. Extending an interface with other interfaces doesn't really mean the subinterface inherits from the superinterface, but rather that the subinterface is, in essence, a concatenation of the methods defined in the two.

If a third interface is used to extend the subinterface and provides a conflicting method declaration, it's essentially the same as if you had just provided the same two conflicting methods in the same interface.

Tom
I disagree: Java has multiple interface inheritance and I stated several times in my question that it was about multiple interface inheritance. And then the 'extends' keywords is specifically used. Then quite some consider that multiple interface inheritance is multiple inheritance, because implementation after all is just a detail (implementation doesn't exist at the OOA/OOD level, it is really just an OOP detail). The interface C surely inherits the abstractions defined by A and B and as an OOD to OOP translationist all that I care about are abstractions, not implementation details.
Webinator
@Tom: then to address your second point: it's more complicated than simply trying to provide two conflicting methods in the same class or interface. The example here is the only case where you'll have an interface inheriting (notice the 'extends' keyword again) *from two abstractions* that is not going to work. In all other cases, you can always use multiple interface inheritance in Java.
Webinator
I don't disagree with any particular point of yours, and I'm well aware of the multiple interface extension capability of Java. I was merely pointing out that "it's how you look at it." I know there are distinctions at an object-oriented design level. Yet, when you get right down to it how (beyond semantics, and the fact a class can implement superinterfaces without implementing subinterfaces) is an interface extending another different from providing all of the defined methods in one interface?
Tom
+3  A: 

I'm not sure there is a specific name for it, or at least it doesn't seem to be very commonly used. It's "just" a problem of the implicit mapping of interface methods to class methods; if you could have overloads which differ in return types only, there would be no problem either. So it comes down to an signature/overloading/implicit method mapping problem.

In the "Thinking in Java" online book, there isn't a name for it either. http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm

Just a side-note, C# allows explicit interface implementations, which addresses this problem.

Lucero
Isn't the question being asked the same as the situation for I4 in the section "Name collisions when combining interfaces" from your link? So I guess it's called "name collisions when combining interfaces" Am I misunderstanding?
MatrixFrog
@MatrixFrog: Yeah, but "name collisions when combining interfaces" sounds more like a description of the issue to me, and not like a "standard" name for the issue.
Lucero
+1  A: 

I don't remember if I have ever seen any name for this. In Java Language Specification there is no name for this either.

Lauri
+2  A: 

JLS §6.4.4, The Members of an Interface Type calls such duplicate superinterface members ambiguous, and requires a compile-time error. I was hoping for something colorful such as the Beaujolais Effect, Heisenbug, et al. Maybe two's-a-crowd?

trashgod
+2  A: 

I also don't know of any specific name for this problem. Whenever it arised it was described in a sentence containing the words return type incompatibility at some point. You could also call it the Map/Set incompatibilty as this is one of the more prominent and annoying examples in the Java class libraries. It makes it impossible to have the same class implement Map as well as Set or Collection just because Map defines a remove(Object) method with a different return type than Collection.

public interface Collection<E> extends Iterable<E> {
    boolean remove(Object o);
}
public interface Set<E> extends Collection<E> {
}
public interface Map<K,V> {
    V remove(Object key);
}
x4u