内部类
定义:将一个类定一个在另一个类的内部定义,就是内部类。
创建内部类
如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,需要具体的指明: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的。
匿名内部类与正规的继承相比有些受限,因为匿名内部类既可以扩展类,也可以扩展接口,但是不能两者兼得,而且如果是实现接口,也只能实现一个接口。
嵌套类
如果不需要内部类对象和其外围类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类(静态内部类)。普通的内部类对象隐式的保存了一个指向创建它的外围类对象的引用。然而,当内部类是static时,就不是这样了。嵌套类意味着:
要创建嵌套类的对象,并不需要其外围类的对象。
不能从嵌套类的对象中访问非静态的外围类对象。
嵌套类与普通类还有一个区别。普通内部类的方法与字段,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含这些。
从多层嵌套类中访问外部类的成员
内部类能够透明的访问所有它所嵌入的外围类的所有成员。
内部类的优势
每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个实现,对于内部类都没影响。内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效的实现了“多重继承”。也就是说,内部类允许继承多个非接口类型(类或抽象类)。
我的理解是,一个外围类可一通过多个内部类去继承多个类或抽象类,从而实现了多重继承的效果。所以内部类也是实现多重继承的关键技术。
局部内部类
在代码块中创建的内部类。局部内部类不能有访问说明符,因为它不是外围类的一部分。但是它可以访问当前代码块内的常量,以及比外围类的所有成员。