9

这是一个在 Java 中使用多接口继承的示例,但存在一个问题。

请注意,我完全知道为什么会出现问题,这不是我的问题的重点。问题是如何命名这种特定的多接口继承歧义,如果有名称的话。

例如,在 C++ 中,当您使用多重实现继承并且无法确定要使用哪个覆盖方法时出现的歧义称为“钻石问题”:

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

现在再一次,我知道这不是同一个问题:这不是重点。关键是在之前的案例中已经创造了一个名称。

我想知道我将要描述的问题是否存在名称。

这是另一种多重继承的示例,其中一个接口继承自其他两个具有不兼容方法返回类型的接口:

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

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

interface MI extends A, B {...}

(注意使用 'extends' 关键字在工作中的多接口继承)

你不能这样做,因为:

A 型和 B 型不兼容;都定义了 c() 但返回类型不相关

有没有创造一个名字来描述这种情况?

4

7 回答 7

3

JLS §6.4.4,接口类型的成员调用此类重复的超接口成员ambiguous,并且需要编译时错误。我希望有一些丰富多彩的东西,例如博若莱效应海森堡也许两人一组

于 2010-02-14T18:21:15.403 回答
3

我不确定它有一个特定的名称,或者至少它似乎不是很常用。这“只是”接口方法到类方法的隐式映射问题;如果您可以有仅在返回类型上有所不同的重载,那么也不会有问题。所以归结为签名/重载/隐式方法映射问题。

在“Thinking in Java”在线书籍中,也没有它的名称。 http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm

顺便说一句,C# 允许显式接口实现,从而解决了这个问题。

于 2010-02-14T17:25:51.103 回答
2

我也不知道这个问题的任何具体名称。每当它出现时,它都会在一个包含返回类型不兼容词的句子中进行描述。您也可以将其称为Map/Set 不兼容,因为这是 Java 类库中比较突出和烦人的示例之一。仅仅因为 Map 定义了一个具有与 Collection 不同的返回类型的remove(Object)方法,就不可能让同一个类实现 Map 以及 Set 或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);
}
于 2010-02-14T18:26:46.713 回答
1

我不记得我是否见过任何名字。在Java 语言规范中也没有这个名称。

于 2010-02-14T17:31:20.543 回答
1

我不愿将其称为多重继承问题,因为接口只是描述得很好,接口——实现类必须定义的一组方法——而不是任何实现。用其他接口扩展一个接口并不意味着子接口继承自超接口,而是子接口本质上是两者中定义的方法的串联。

如果使用第三个接口来扩展子接口并提供冲突的方法声明,则本质上与您刚刚在同一接口中提供了相同的两个冲突方法相同。

于 2010-02-14T17:25:26.470 回答
0

您描述的问题存在于 .NET 和 Java 中,但有一个简单的解决方案:.NET 框架允许类使用具有不同名称的类成员来实现接口成员。因此,尽管实现两个仅返回类型不同的接口成员的类方法需要具有不同的名称,但这并不排除它们实现具有相同名称的接口成员的能力。

如果一个接口继承了两个具有冲突成员的接口,则实现复合接口的类可以实现这些成员,就像它直接继承了冲突的接口一样。如果不将引用转换为其他接口类型之一,组合接口的使用者通常无法使用任一组件接口的成员,但所讨论的转换将被视为向上转换而不是向下转换。

.NET 中实现的方案在那里工作得很好。不幸的是,没有办法在 Java 中做任何类似的事情。我不知道如果一个接口继承了具有冲突成员的其他接口,Java 会发出声音,但无论它是否在那个时候发出声音,都没有办法生成一个可以实现它的类。

于 2013-12-18T00:11:51.507 回答
-2

我认为没有定义名称,因为 Java 中的接口不能具有方法实现,因此可以避免这个问题,因为特定方法总是只有一个实现,因此不会出现歧义。

我错过了重点还是您在谈论“c”变量?

于 2010-02-14T17:23:03.017 回答