💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## [内部类可以被覆盖么?](https://lingcoder.gitee.io/onjava8/#/book/11-Inner-Classes?id=%e5%86%85%e9%83%a8%e7%b1%bb%e5%8f%af%e4%bb%a5%e8%a2%ab%e8%a6%86%e7%9b%96%e4%b9%88%ef%bc%9f) 如果创建了一个内部类,然后继承其外部类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被覆盖吗?这看起来似乎是个很有用的思想,但是“覆盖”内部类就好像它是外部类的一个方法,其实并不起什么作用: ~~~ // innerclasses/BigEgg.java // An inner class cannot be overridden like a method class Egg { private Yolk y; protected class Yolk { public Yolk() { System.out.println("Egg.Yolk()"); } } Egg() { System.out.println("New Egg()"); y = new Yolk(); } } public class BigEgg extends Egg { public class Yolk { public Yolk() { System.out.println("BigEgg.Yolk()"); } } public static void main(String[] args) { new BigEgg(); } } ~~~ 输出为: ~~~ New Egg() Egg.Yolk() ~~~ 默认的无参构造器是编译器自动生成的,这里是调用基类的默认构造器。你可能认为既然创建了**BigEgg**的对象,那么所使用的应该是“覆盖后”的**Yolk**版本,但从输出中可以看到实际情况并不是这样的。 这个例子说明,当继承了某个外部类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。当然,明确地继承某个内部类也是可以的: ~~~ // innerclasses/BigEgg2.java // Proper inheritance of an inner class class Egg2 { protected class Yolk { public Yolk() { System.out.println("Egg2.Yolk()"); } public void f() { System.out.println("Egg2.Yolk.f()"); } } private Yolk y = new Yolk(); Egg2() { System.out.println("New Egg2()"); } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); } } public class BigEgg2 extends Egg2 { public class Yolk extends Egg2.Yolk { public Yolk() { System.out.println("BigEgg2.Yolk()"); } @Override public void f() { System.out.println("BigEgg2.Yolk.f()"); } } public BigEgg2() { insertYolk(new Yolk()); } public static void main(String[] args) { Egg2 e2 = new BigEgg2(); e2.g(); } } ~~~ 输出为: ~~~ Egg2.Yolk() New Egg2() Egg2.Yolk() BigEgg2.Yolk() BigEgg2.Yolk.f() ~~~ 现在**BigEgg2.Yolk**通过**extends Egg2.Yolk**明确地继承了此内部类,并且覆盖了其中的方法。`insertYolk()`方法允许**BigEgg2**将它自己的**Yolk**对象向上转型为**Egg2**中的引用**y**。所以当`g()`调用`y.f()`时,覆盖后的新版的`f()`被执行。第二次调用`Egg2.Yolk()`,结果是**BigEgg2.Yolk**的构造器调用了其基类的构造器。可以看到在调用`g()`的时候,新版的`f()`被调用了。