Java之内部类可以被覆盖吗详解(附源码)

Posted mufeng_慕枫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之内部类可以被覆盖吗详解(附源码)相关的知识,希望对你有一定的参考价值。

前言


       如果创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被覆盖吗?这看起来似乎是个很有用的思想,但是“覆盖”内部类就好像它是外围类的一个方法,其实并不起什么作用:

示例源码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()被调用了。





以上是关于Java之内部类可以被覆盖吗详解(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

Java之内部类的初级应用详解(附源码)

Java之内部类与向上转型详解(附源码)

Java之内部类链接到外部类(外围类)详解(附源码)

Java之内部类的继承(附源码)

Java之局部内部类和匿名内部类的区别详解(附源码)

Java面向对象之内部类的详解