为什么Java类只能继承一个类但可以实现多个接口?

7

在C++中,您可以扩展多个类,那么Java中一个类只能继承一个类的设计有什么优势呢? 由于接口是一种纯粹的类(实际上是抽象类),为什么不像类扩展一样限制接口实现的数量呢?


3
将类继承限制为单一父类有明显的好处(如 Chris Hayes 的回答 所述)。那么限制一个类可以实现的接口数量有什么目的或好处呢? - Ted Hopp
将接口称为抽象类是不正确的。抽象类可以在其中具有实现逻辑,并且具有与接口不同的默认可见性。 - Chris Hayes
@ChrisHayes - OP说“一种纯粹的”抽象类。在C++中,纯虚函数没有实现;我认为OP的意思是Java接口就像一个只有纯虚函数(完全没有实现逻辑)的C++类。 - Ted Hopp
朋友,我建议你阅读一本好的Java书籍。Kathy Sierra的书是其中之一。 - The PowerHouse
1个回答

23

只能扩展一个基类是解决菱形继承问题的一种方法。当一个类扩展了两个都实现了同名方法的基类时,产生了该问题 - 如何知道应该调用哪个方法?

A.java:

public class A {
    public int getValue() { return 0; }
}

B.java:

public class B {
    public int getValue() { return 1; }
}

C.java:

public class C extends A, B {
    public int doStuff() { 
        return super.getValue(); // Which superclass method is called?
    }
}

由于接口不能有实现,因此就不会出现同样的问题。如果两个接口包含具有相同签名的方法,则实际上只有一个方法,仍然不存在冲突。


1
我也在维基百科上看到了这个问题,但我并不完全满意。有一些例子是通过按特定顺序处理方法继承来解决钻石问题的(因此C首先获得B的方法,然后是A的方法)。 - Makoto
@Makoto 有人很容易地争辩说这不是一个好的行为。Java的创造者显然也持有这种观点。 - Chris Hayes
@Makoto - 这解决了某些问题,但是行为的多重继承总是会有问题。如果一个人需要函数a()的一个顺序和函数b()的不同顺序,那么固定顺序就无法解决任何问题。 - Ted Hopp
@Makoto - 拥有固定的执行顺序也会让查看和调试代码的其他人感到困惑。检查正确实现将是一个巨大的维护难题。此外,在一个 c++ 场景中,如果父类 A 和 B 都有 2 个函数,并且我想要从 A 中获取第一个函数和从 B 中获取第二个函数,那么这个顺序并没有帮助。 - Srihari
只需指定方法即可,例如如果您有父类a和父类b以及扩展a和b的子类c。如果它们都有方法foo(),那么只需a.super.foo()和b.super.foo()。 - George Xavier
@GeorgeXavier 如果您实例化一个 C 并尝试在该对象上调用 getValue,那么 C 的用户应该选择使用哪个超类?虽然这不是无法解决的问题,但每种解决方案(包括拒绝多重继承)都有其权衡。防止出现这种情况是 Java 使用的解决方案,是的,它也有其缺点。 - Chris Hayes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接