【问题标题】:Inconsistent class hierarchy不一致的类层次结构
【发布时间】:2014-11-16 07:31:07
【问题描述】:
我读过关于类构造函数here 的内容,然后出现一个问题,为什么以下层次结构不正确:
public class Test extends Subclass.Inner{ //compile-time error
//The hierarchy of the type Test is inconsistent
public Test() {
super();
}
}
public class Subclass extends Test{
public class Inner{
}
}
正式
如果超类构造函数调用语句不合格,并且
如果 S 是一个内部成员类,那么它是一个编译时错误,如果 S 是
通过声明不是 C 的词法封闭类的成员或
继承。
我认为这个例子完全符合我引用的规则。在这种情况下,SubClass 是 Test 通过继承的词法封闭类。为什么代码不能正常工作?您能否提供一个适当的例子来反映这一点?
【问题讨论】:
标签:
java
class
inheritance
【解决方案1】:
一个内部类的实例必须有一个封闭的实例,它在内部类实例之前被初始化。另一方面,超类构造函数总是在子类构造函数之前执行。因此,创建SubClass的实例需要先调用Test的构造函数,这需要先调用SubClass.Inner的构造函数,但SubClass.Inner不能在其包含的实例之前初始化。
我相信为了满足你引用的条件,超类 Inner 必须被一个超类 Test 包围。在您的情况下,它包含在 Test 的子类中。
【解决方案2】:
内部实例类(非静态)实际上是这样转换的:
public class Subclass extends Test {
public class Inner {
}
}
变成这样:
public class Subclass extends Test {
}
public class Inner {
Subclass parent;
public Inner(Subclass parent) {
this.parent = parent;
}
}
以下内容有效:
public class Container extends Subclass {
public class Test extends Subclass.Inner {
public Test() {
super();
}
}
}
public class Subclass {
public class Inner {
}
}
【解决方案3】:
这是您缺少的一个子句 (8.4.1):
如果 T 在 C 的 extends 或 implements 子句中作为超类或超接口,或作为超类或超接口名称。
如果满足以下任一条件,则一个类 C依赖于引用类型 T:
- C 直接依赖于依赖于 T 的类 D(递归使用此定义)。
如果一个类依赖于它自己,这是一个编译时错误。
这是一个编译时错误,因为Subclass 的超类声明包含Subclass 作为超类名称的限定符。
除了您在此处进行的极其奇怪的循环定义之外。 Test 将是其自身的外部范围。
这也不能编译,虽然它不像内部类那么令人费解:
class Test implements Test.ITest {
interface ITest {}
}
Netbeans 给了我一个更直接的错误,即存在“循环继承”。类声明不允许以这种方式引用自身。