[think in java]第10章 内部类

内部类

定义:将一个类定一个在另一个类的内部定义,就是内部类。


创建内部类

如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,需要具体的指明:outerClassName.InnerClassName;


链接到外部类

内部类能访问其外围对象的所有成员,不需要任何特殊条件。


使用.this与.new

.this用法

如果你需要生成对外部类对象的引用,可以后外部类的名字后面紧跟圆点和this。这一点在编译期就被知晓并受到检查,因此没有任何运行时开销。看下面的例子:

public class DotThis {
	void f(){ System.out.println("DotThis.f()");}
	
	public class Inner{
		public DotThis outer(){
			return DotThis.this;  //here
			//a plain "this" would be Inner's this
		}
	}
	
	public Inner inner(){ return new Inner();}
	public static void main(String [] args){
		DotThis dt = new DotThis();
		DotThis.Inner dti= dt.inner();
		dti.outer().f();
	}

}
output:
DotThis.f()

.new用法

要创建内部类对象,需要用外部类对象的引用后跟.new来完成。如下例子:

public class DotNew {
	public class Inner{}
	public static void main(String [] args){
		DotNew dn = new DotNew();
		DotNew.Inner dni = dn.new Inner();
		//注意:用.new创建内部类时,使用外部类对象dn,而非外部类的名字DotNew
	}
}

由于创建内部类时需要用到外部类对象,所以在拥有外部类对象之前是不可能创建内部类对象的。但有一种情况例外,就是创建的内部类是静态内部类(此处需注意,是静态内部类,而非静态外部类   why?)。


在方法和作用域内的内部类

可以在方法或任意的作用域定义内部类。看下面的一个例子:

public class Parcel5 {
	//此处Destination 是一个接口  具体定义未给出
	public Destination destination(String s){
		class PDestination implements Destination{
			private String label;
			private PDestination(String whereTo){
				label = whereTo;
			}
			public String readLabel(){ return label;}
		}
		return new PDestination(s);
	}
	public static void main(String [] args){
		Parcel5 p = new Parcel5();
		Destination d = p.destination("Tasmania");
	}

}

PDestination类是destination方法的一部分,是方法的内部类。在destination()方法之外不能访问PDestination。return语句进行了向上转型。另外,在Destination中定义的内部类PDestination,并不意味着dest()方法执行完毕,PDestination就不可用了。


匿名内部类

先看个例子:

public class Parcel7 {
	public Contents contents(){
		//此处Contents 是一个接口  具体定义未给出
		return new Contents(){ //insert a class definition
			private int i = 11;
			public int value(){ return i;}
		};
	}
	
	public static void main(String [] args){
		Parcel7 p = new Parcel7();
		Conents c = p.contents();
	}
}
contents方法中用到了匿名内部类。在创建Content对象的同时,插入了一个对匿名内部类的定义。如果在一个匿名内部类中希望它使用一个在其外部定义的对象,那么编译器会要求其参数是final的。

匿名内部类与正规的继承相比有些受限,因为匿名内部类既可以扩展类,也可以扩展接口,但是不能两者兼得,而且如果是实现接口,也只能实现一个接口

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。