7

我很困惑为什么这是允许的

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 {
    }
}

这里发生了什么?我在哪里可以找到有关内部类继承如何工作的更多信息?

编辑我想到了两个相当糟糕的想法;内部类扩展外部类,内部类扩展其他静态内部类。我不确定到底发生了什么以及我应该如何重构它。我最终只是抽出内部类并将它们封装在外部类中。

4

4 回答 4

6

首先:不要做这种事情。这是邪恶的。真的,Java 1.1 的规定应该更加严格,IMO。

thisFoo.Fooey构造函数中使用哪个存在混淆。外部的 this ( Foo.this) 会起作用。但实际this是 aFoo但它不能传递给超级this构造函数,因为在超级构造函数返回之前使用的规则(并且除了具有与内部实例相同的外部实例之外)。由于((Bar)this).this$0this.

解决方案是明确的。在我的书中,显式通常是一件好事(除非它成为样板文件)。

public class Foo {
    class Bar extends Foo {

    }

    class Fooey extends Bar {
        Fooey() {
            Foo.this.super();
        }
    }
}

更好的是,不要让内部类扩展它自己的外部类,或扩展任何内部类。

于 2009-10-19T16:24:25.017 回答
1

我想 JLS 和这个问题的答案是一个起点

Java内部类和静态嵌套类

内部类和封闭实例

于 2009-10-19T16:05:44.883 回答
1

汤姆霍廷的回答是正确的。

也看看javauzzler。示例章节包含此案例和其他一些您可能想查看的“有趣”案例。

于 2009-10-19T16:44:37.940 回答
1

(还不能评论 - 我需要 50 个代表)

我也很困惑,这是允许的。外部类的(非静态)内部类实际上是该外部类的成员。阅读:内部对象是其外部对象的成员。(顺便说一句,每个外部对象都必须拥有一个内部对象,但这不是重点。)

我喜欢使用的类比是这样的:让我们Car成为外部类,让我们Wheel成为内部类。must的每个实例Car,并且确实有至少一个实例Wheel作为成员。

现在,内部类扩展外部类在概念上没有意义。我想不出任何现实世界的情况需要一个对象既是成员又是另一个对象的类型。集合论者会回忆起规律性公理及其后果。

可以这样想:让Hondaextend Car,让Honda成为一个嵌套在里面的内部类Car。你在这里说的是每个Honda对象都是一个 Car对象(duh),每个Car对象都有一个 Honda对象。这些陈述中只有一个有意义,但在 Java 中两者都允许为真。

或者回到前面的类比,你不应该让WheelextendCar因为那样 aWheela Car,并且根据定义必须another Wheel,顺便说一下,这是 a Car,所以必须有 a Wheel和永远永远阿门。构造一个Car对象会导致嵌套对象的无限循环。

我很不高兴这是合法的并且不会产生编译时错误。

于 2011-08-10T14:33:39.293 回答