从外类和其他内部类别对内部类进行子类化

时间:2009-10-19 15:52:55

标签: java inheritance inner-classes

我很困惑为什么允许这样做

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 个答案:

答案 0 :(得分:6)

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

对于this构造函数中使用Foo.Fooey的问题存在疑惑。外部(Foo.this)可以工作。但实际的thisFoo,但由于在超级构造函数返回之前使用this的规则(并且除了使外部实例具有与之相同的实例)之外,它不能传递给超构造函数。内部实例很糟糕)。由于使用((Bar)this).this$0的限制,超类“this”(IIRC)上的外部也是无法访问的。

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

public class Foo {
    class Bar extends Foo {

    }

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

更好的是,没有内部类扩展自己的外部类,或者扩展任何内部类。

答案 1 :(得分:1)

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

Java inner class and static nested class

Inner Classes and Enclosing Instances

答案 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对象将导致嵌套对象的无限循环。

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