[英]Cyclic inheritance hierarchy in Java
我知道Java中不允许使用循环继承层次结构。 编译器会抛出错误,但我真正感兴趣的是知道编译失败的确切原因。
class A extends B{}
class B extends C{}
class C extends A{} // this will give you compile time error.
编译器抛出错误的原因是什么,我编写代码class C extends A{}
的时刻class C extends A{}
这种关系根本不可能。 它定义了一个无限递归类。 为了定义class C
,您需要class A
,定义class A
需要class B
,定义class B
class C
需要class C
- 然后返回起点。 这是无限的,所以编译器不能这样做,它也没有逻辑意义。
只看一下extends这个词,在Java中,一个子类真正扩展了它的超类。 这意味着子对象是它的所有超级对象加上一些新成员和一些指定成员。
怎么可以
我们可以说扩展是一个顺序关系所以: A扩展B意味着A <B (甚至不是A <= B),然后在你的情况下B <C ,所以很明显C不能小于A.
有一个非常实际的问题(除了在其他答案中解释的逻辑问题):
必须在实例化期间初始化类。 这是通过首先初始化超类在Java中完成的。 当你有一个循环时,初始化代码上升到继承阶梯并尝试初始化从未到达的超类...
因此,对于Java,必须禁止这样做。
我们可以将问题从C
IS-A B
减少到这些语句:
class A extends C{}
class C extends A{}
显然这是一个冲突,因此编译器会给出错误。
循环继承可以有两个例子:
1. A类扩展A {}: - 这没有任何意义,因为A类的成员已经存在于A类中,那么为什么要扩展。
2. A类扩展B {},B类扩展A {}: - 在这种情况下,两个类的成员可以写在一个类中,然后为什么要编写两个类并相互扩展。
由于上述用例无效,因此Java不支持循环继承。
我以为我会在这个帖子中添加一个尚未说明的Java特定答案。 在Java中,每个类最终都必须从Object
类派生。 这就是为什么每个对象都可以毫无问题地转换为Object
实例的原因。 为了支持这一事实, Java继承教程指出:
Excepting Object,没有超类,每个类都有一个且只有一个直接超类(单继承)。 在没有任何其他显式超类的情况下,每个类都隐式地是Object的子类。
类可以从派生自类的类派生的类派生,依此类推,最终派生自最顶层的类Object。 据说这样的类是继承链中延伸回Object的所有类的后代。
如果允许循环继承依赖,并且因为Java中的类必须只有一个直接超类(参见上文),那么任何循环依赖链中的类实例(例如,类A
, B
和C
实例)都不能从Object
,不允许。 因此,这些循环依赖项对象都不能被视为Object
。 因此,编译器必须禁止循环依赖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.