Java:你怎么称这种多重继承模糊?

时间:2010-02-14 17:13:57

标签: java inheritance multiple-inheritance diamond-problem

这是一个在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()但具有不相关的返回   型

是否创造了一个名称来描述这种情况?

7 个答案:

答案 0 :(得分:3)

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

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

只是旁注,C#允许显式接口实现,解决了这个问题。

答案 1 :(得分:3)

JLS §6.4.4, The Members of an Interface Type调用此类重复的超级接口成员 不明确 ,并且需要编译时错误。我希望有一些丰富多彩的东西,比如Beaujolais EffectHeisenbuget al。也许两个人群

答案 2 :(得分:2)

我也不知道这个问题的具体名称。每当它出现时,它在一个句子中描述,其中包含单词 return type incompatibility 。您也可以将其称为 Map / Set incompatibilty ,因为这是Java类库中更为突出和烦人的示例之一。它使得无法使用相同的类实现Map以及Set或Collection,因为Map定义了一个 remove(Object)方法,其返回类型与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);
}

答案 3 :(得分:1)

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

如果使用第三个接口来扩展子接口并提供冲突的方法声明,那么它基本上就像你在同一个接口中提供了相同的两个冲突方法一样。

答案 4 :(得分:1)

我不记得我是否见过这个名字。在Java Language Specification中,没有任何名称。

答案 5 :(得分:0)

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

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

在.NET中实现的方案在那里很好用。不幸的是,在Java中没有办法做类似的事情。我不知道如果一个接口继承了具有冲突成员的其他接口,Java会发出尖叫声,但是不管它是否在那个时候发出声响,就没有办法生成一个可以实现它的类。

答案 6 :(得分:-2)

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

我是否错过了这一点,或者你在谈论'c'变量?