我很困惑为什么允许这样做
public class Foo {
class Bar extends Foo {
}
}
但这是不允许的
public class Foo {
class Bar extends Foo {
}
class Fooey extends Bar {
}
}
编译器通知它在调用超类型构造函数之前无法引用Fooey.this。
这是允许的
public class Foo {
static class Bar extends Foo {
}
class Fooey extends Bar {
}
}
这里发生了什么?我在哪里可以找到有关内部类继承如何工作的更多信息?
编辑我遇到了两个相当糟糕的想法;内部类扩展外部类,内部类扩展其他静态内部类。我不确定到底发生了什么以及我应该如何重构这一点。我最终只是将内部类拉出来并将它们封装在外部类中。
答案 0 :(得分:6)
首先:不要做这种事情。这是邪恶的。实际上,应该更加严格地规定Java 1.1,IMO。
对于this
构造函数中使用Foo.Fooey
的问题存在疑惑。外部(Foo.this
)可以工作。但实际的this
是Foo
,但由于在超级构造函数返回之前使用this
的规则(并且除了使外部实例具有与之相同的实例)之外,它不能传递给超构造函数。内部实例很糟糕)。由于使用((Bar)this).this$0
的限制,超类“this
”(IIRC)上的外部也是无法访问的。
解决方案是明确的。明确在我的书中通常是一件好事(除非它成为样板)。
public class Foo {
class Bar extends Foo {
}
class Fooey extends Bar {
Fooey() {
Foo.this.super();
}
}
}
更好的是,没有内部类扩展自己的外部类,或者扩展任何内部类。
答案 1 :(得分:1)
答案 2 :(得分:1)
还要看java puzzler。示例章节包含此案例以及您可能希望查看的其他一些“有趣”案例。
答案 3 :(得分:1)
(无法评论 - 我需要50个代表)
我也很困惑,这是允许的。外部类的(非静态)内部类实际上是该外部类的成员。读:内部对象是其外部对象的成员。 (顺便说一句,每个外部对象必须拥有一个内部对象,但这不是重点。)
我喜欢使用的类比是:让Car
成为外部类,让Wheel
成为内部类。 Car
的每个实例都必须且确实至少有一个Wheel
实例作为成员。
现在,内部类扩展外部类并没有概念意义。我想不出任何要求对象既是成员又是另一个对象类型的真实情况。 Set Theorists将回忆 Axiom of Regularity 及其后果。
以这种方式思考:让Honda
扩展Car
,让Honda
成为嵌套在Car
内的内部类。你在这里说的是每个Honda
对象是 Car
对象(duh),每个Car
对象都有 Honda
对象。这些语句中只有一个是有意义的,但在Java中都允许这两个语句都是正确的。
或者回到上一个类比,你不应该让Wheel
延长Car
,因为Wheel
一个Car
,根据定义,必须 另一个Wheel
,顺便说一下是 Car
,所以必须 { {1}}永远和永远的阿门。构造Wheel
对象将导致嵌套对象的无限循环。
我很不高兴这是合法的,并且不会产生编译时错误。