前言
如果创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被覆盖吗?这看起来似乎是个很有用的思想,但是“覆盖”内部类就好像它是外围类的一个方法,其实并不起什么作用:
示例源码1
package com.mufeng.thetenthchapter; class Egg { private Yolk y; public Egg() { // TODO Auto-generated constructor stub System.out.println("new Egg()"); y = new Yolk(); } protected class Yolk { public Yolk() { // TODO Auto-generated constructor stub System.out.println("Egg.Yolk()"); } } } public class BigEgg extends Egg { public class Yolk { public Yolk() { // TODO Auto-generated constructor stub System.out.println("BigEgg.Yolk()"); } } public static void main(String[] args) { new BigEgg(); } }
输出结果1
new Egg() Egg.Yolk()
源码解析1
默认的构造器是编译器自动生成的,这里是调用基类的默认构造器。你可能认为既然创建了BigEgg的对象,那么所使用的应该是“覆盖后”的Yolk版本,但从输出中可以看到实际情况并不是这样的。
这个例子说明,当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。当然,明确地继承某个内部类也是可以的:
示例源码2
package com.mufeng.thetenthchapter; class Egg2 { private Yolk y = new Yolk(); public Egg2() { // TODO Auto-generated constructor stub System.out.println("new Egg2()"); } protected class Yolk { public Yolk() { // TODO Auto-generated constructor stub System.out.println("Egg2.Yolk()"); } public void f() { System.out.println("Egg2.Yolk().f()"); } } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); } } public class BigEgg2 extends Egg2 { public BigEgg2() { // TODO Auto-generated constructor stub insertYolk(new Yolk()); } public class Yolk extends Egg2.Yolk { public Yolk() { // TODO Auto-generated constructor stub System.out.println("BigEgg2.Yolk()"); } public void f() { System.out.println("BigEgg2.Yolk().f()"); } } public static void main(String[] args) { Egg2 e2 = new BigEgg2(); e2.g(); } }
输出结果2
Egg2.Yolk() new Egg2() Egg2.Yolk() BigEgg2.Yolk() BigEgg2.Yolk().f()
源码解析2
现在BigEgg2.Yolk()通过extends Egg2.Yolk()明确地继承了此内部类,并且覆盖了其中的方法。insertYolk()方法允许BigEgg2将它自己的Yolk对象向上转型为Egg2中的引用y。所以当g()调用y.f()时,覆盖后的新版本的f()被执行。第二次调用Egg2.Yolk(),结果是BigEgg2.Yolk的构造器调用了其基类的构造器。可以看到在调用g()的时候,新版的f()被调用了。
时间: 2024-08-29 03:43:19