Java基础10--多态--内部类(四)

2014-11-24 07:43:00 · 作者: · 浏览: 2
t in = new Inner(); return in; } } class InnerClassDemo { public static void main(String[] args) { Outer out = new Outer(); Object obj = out.method(); } }

10-14,匿名内部类-概述

匿名内部类就是内部类的简写格式。

必须有的前提是:

内部类必须继承或实现一个外部类或接口。

匿名内部类:

其实就是一个匿名子类对象。

格式:

new父类 or 接口() { 子类内容 }

例如:

abstract class Demo {
	abstract void show();
}
class Outer {
	int num = 4;
	/* 非匿名方法
	class Inner extends Demo {
		void show() {
			System.out.println("show ... " + num);
		}
	}
	*/
	public void method() {
		//new Inner().show(); //对应上面非匿名方法,
		new Demo { //匿名内部类,继承了外部类Demo
		//new了一个匿名子类对象并调用show方法,子类中重写Demo的抽象方法
			void show() {
				System.out.println("show ..." + num);
			}
		}.show();
	}
}
class InnerClassDemo {
	public static void main(String[] args) {
		new Outer().method();//new 一个Outer对象并调用其method方法。
	}
}

10-15,匿名内部类-应用

使用场景:

当函数参数是接口类型时,而且接口中的方法不超过三个。

可以用匿名内部类作为实际参数进行传递。

class InnerClassDemo {
	class Inner {}
	public static void main(String[] args) {
		/* 接口类型参数传递,在传递时直接实现方法
		show(new Inter(){
			public void show1() {
				System.out.println("show1...");
			}
			public void show2() {
				System.out.println("show2...");
			}
		});
		*/
		new Inner();
	}
	public void method() {
		new Inner();
	}
	public static void show(Inter in) {//接口形参
		in.show1();
		in.show2();
	}
}
interface Inter {
	void show1();
	void show2();
}
class Outer {
	/* 非匿名方式
	class Inner implements Inter {
		public void show1() {
			System.out.println("show1...");
		}
		public void show2() {
			System.out.println("show2...");
		}
	}
	*/
	public void method() {
		Inner in = new Inner();
		in.show1();
		in.show2();
		//给匿名内部类起个名字,用该名字调用里面的show1,show2方法。
		Inter in = new Inter() {
			public void show1() {
				System.out.println("show1...");
			}
			public void show2() {
				System.out.println("show2...");
			}
		};
		in.show1();
		in.show2();
	}
}

若匿名内部类中只有一个方法,可以这么调用:

new Inter() {
	public void show() {
		System.out.println("show run ... ");
	}
}.show();

10-16,匿名内部类-细节

class Outer {
	void method() {
		//前面的Object表示父类对象,后面的Object表示子类对象。
		//这里是多态,把new Object向上转型为Object型,编译时看等号左边,
		//因为Object类中没有show方法,所以编译失败。
		Object obj = new Object() {
			public void show() {
				System.out.println("show run ... ");
			}
		};
		obj.show(); // 报错,找不到show方法。
	}
}
class InnerClassDemo {
	public static void main(String[] args) {
		new Outer().method();
	}
}

报错原因:因为匿名内部类这个子类对象被向上转型为了Object类型,这样就不能再使用子类的特有方法了。

10-17,对象的初始化过程:

代码示例:

class Fu {
	int num = 9;
	{ // 构造代码块
		System.out.println("Fu"); //第一步:打印 Fu
	}
	Fu() {
		super();
		//显示初始化
		//构造代码块初始化
		show();
	}
	void show() {
		//这个show会被子类的show覆盖
		System.out.println("fu show " + num); //第二步:打印Zi类中的show:Zi show 0
	}
}
class Zi extends Fu {
	int num = 8;
	{
		System.out.println("Zi"); //第三步:打印 Zi
	}
	Zi() {
		super();
		//显示初始化
		//构造代码块初始化
		show();
	}
	void show() {
		System.out.println("Zi show " + num); //第四步:打印Zi show 8
	}
}
public class Demo {
	public static void main(String[] args) {
		new Zi();
	}
}

步骤:

(1)Demo类加载进方法区,Demo的构造函数加载进方法区。

(2)main方法加载进静态方法区,main进栈。

(3)new Zi()在堆中创建子类对象,在这个内存块中开辟两块空间,分别为Zi的num = 0,Fu的num = 0。

(4)Fu类先加载进方法区,Zi类后加载进方法区。

(5)new Zi();时调用Zi的构造函数,Zi中的super调用Fu的构造函数,Fu()先执行super这里super调用的是Object,然后执行成员变量的显示初始化,然后执行本类中构造代码块的初始化,这时输出Fu,然后再执行sho