代码之家  ›  专栏  ›  技术社区  ›  sal

从外部类到其他内部类的子类化内部类

  •  7
  • sal  · 技术社区  · 17 年前

    我不明白为什么允许这样做

    public class Foo {
        class Bar extends Foo {
        }
    }
    

    但这是不允许的

    public class Foo {
        class Bar extends Foo {
        }
    
        class Fooey extends Bar {
        }
    }
    

    编译器通知它不能引用fooey。这是在调用父类型构造函数之前。

    这是允许的

    public class Foo {
        static class Bar extends Foo {
        }
    
        class Fooey extends Bar {
        }
    }
    

    这是怎么回事?我在哪里可以找到更多关于内部类继承如何工作的信息呢?

    编辑 我遇到了两个相当糟糕的想法:内部阶级延伸到外部阶级,内部阶级延伸到其他静态的内部阶级。我不知道到底发生了什么,我应该如何重构这个。最后我把内部类拉出并封装到外部类中。

    4 回复  |  直到 15 年前
        1
  •  6
  •   Tom Hawtin - tackline    17 年前

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

    关于哪一个有点困惑 this 从中使用 Foo.Fooey 构造函数。外面的这个( Foo.this 可以工作。但实际 这 是一个 Foo 但由于使用规则的限制,它不能传递给超级结构 这 在超级结构返回之前(并且除了有一个外部实例外,还包括与内部实例相同的实例)。超类上的外部这个” ((Bar)this).this$0 “(IIRC),由于使用限制,也无法访问 这 .

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

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

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

        2
  •  1
  •   Community Mohan Dere    9 年前
        3
  •  1
  •   vdr    17 年前

    汤姆·霍丁的回答是正确的。

    也可以看看 java puzzler . 示例章节包含这个案例和其他一些您可能想看的“有趣”案例。

        4
  •  1
  •   chharvey    15 年前

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

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

    我喜欢用这个比喻:让 Car 做个外行 Wheel 做一个内行。的每个实例 小型车 必须至少有一个 车轮 作为会员。

    现在,内部类扩展外部类在概念上没有意义。我想不出任何现实世界中要求一个对象同时是另一个对象的成员和类型的情况。集理论家会回忆起 Axiom of Regularity 及其后果。

    这样想:让我们 Honda 延伸 小型车 让 本田 是嵌套在内部的内部类 小型车 . 你在这里说的是 本田 对象 是一个 小型车 对象(duh),以及每个 小型车 对象 有一个 本田 对象。这些语句中只有一个是有意义的,但是在Java中两者都是允许的。

    或者回到前面的类比,你不应该让 车轮 延伸 小型车 因为那时 车轮 将 是 一 小型车 ,根据定义,必须 有 另一个 车轮 顺便说一下 是一个 小型车 所以必须 有一个 车轮 永远永远阿门。构造 小型车 对象将导致嵌套对象的无限循环。

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