个人觉得大部分内部类都可以使用组合实现,具体使用组合还是内部类看需求而定,内部类可以隐藏细节,但隐藏也就很难重用
在jdk中Collections类中为将某些不同步的容器变为同步的,就是使用了内部类.
内部类是一种名字隐藏和组织代码的模式,它了解外围类并能与之通讯,内部类拥有其外围类所有元素的访问权,并因此可实现多重继承
外部类可以访问内部类的private元素,但要新建一个内部类的实例
内部类的对象只能在与其外部类的对象相关联时才能被创建,因为内部对象要想访问到外部对象的所有成员,必须拥有一个指向外围对象的引用(new Outer().new Inner())
内部类跟普通类一样会被编译,类名形式为 Outer$Inner.class,其中Outer为外围类的类名,Inner为内部类的类名
.this 和 .new
.this可以生成对外部类对象的引用 (如Outer.this 注:Outer为外围类名)。
.new可以创建某个内部类对象(new Outer().new Inner())。
静态内部类(也叫嵌套类)
静态内部类不依赖于外围类实例被实例化,故不能访问外围类中的非静态变量。
静态内部类的实例可以如此创建:new Outer.InnerStatic();
内部类与向上转型
声明接口,并用内部私有private类的形式去实现接口,这将等价于一个向上转型操作。由于内部类可以进入完全不可见状态,所以我们可以非常方便的隐藏实现细节,我们得到的只是一个接口的句柄,而且甚至不知道其准确的类型
可以将内部类建在方法内部或作用域内部来实现隐藏细节(有些复杂的方法可能需要一个类来支撑起实现,而你又不希望别人知道你的方法细节),在方法外部和作用域外此类将不可访问,它可以访问当前代码的常量和所有外围类的变量
匿名内部类
.class文件形式:Outer$1Inner.class (1为数字)编译器会简单的产生一个数字作为匿名内部类的标识符
匿名内部类是内部类的一种方式,这种方式不关心类名,但可被内部类取代
没有名字标识也就不能被重用
接口内的类
嵌套类可以作为接口的一部分,任何在接口内部的类都是public的和static的,只是将嵌套类置于接口的命名空间内(如:ClassInInterface$Test.class)
当需要某个接口的实现共用一段代码时,可以使用内部类的方式
内部类可以多层嵌套,和一层时一样.
为何需要内部类
1.提供某种进入外围类的窗口
2.当需要继承多个接口时,使用内部类使得每个内部类都可以独立地继承一个接口的实现,所有无论外围类是否已经实现了该类的接口,对内部类都没影响,这将提供很高的灵活性
3.相比接口,内部类在解决多重继承时更加有效
4.在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,提高更高的灵活性
5.需要实现的多个接口有方法重名时,使用内部类可以阻止覆盖并实现接口P206
回调的理解参见cap10_exc_Ex23.java
手机的被呼叫就是回调的例子,手机有被呼叫的功能,但你从不调用,回电
内部类和控制框架
通常使用模版方法来定制应用程序框架以控制其流程,见DP_Template
控制框架是一类特殊的应用程序框架,用来解决响应事件的需求(事件驱动程序如GUI)
一个控制框架中的控制器通常维护着系统中的状态信息。如activity中的n种状态、电灯控制器中的开和关等。同时控制器还需维护一个事件event列表。这些事件通常继承于同一个基类,用来改变控制器中的状态信息,这就需要访问到控制器中的变量了。由于内部类可以访问外围类的所有属性包括private,故使用内部类可以实现该需求。另一种方式可能通过传递一个当前控制器的引用来实现,android中的事件很多都用到了XXActivity.this,一方面通过控制反转来回收资源,另一方面改变activity的状态(Intent)。
//一个模拟的浏览器控制器
BrowseController{
//状态信息(用属性表示)
public class OnClick extends Event{}
public class OnDoubleClick extends Event{}
}
从内部类的角度看,内部类即具有自己的属性和方法,又能访问其外围类的属性和方法,也就好像继承了两个类。从外围类的角度看,外围类拥有其内部类的所有引用,也就能访问到其所以public类,从而实现了多重继承。
内部类的继承
内部类的构造器必须连接到指向其外围对象的引用,当需要继承内部类的时候,必须在构造器中使用如下语法
enclosingClassRefence.super();
内部类可以被覆盖吗
当继承某个外围类时,内部类并未发生什么特别神奇的变化,这两个内部类是完全独立的两个实体,各自在各自的命名空间内
在新建一个拥有内部类的外围类实例时,并不会去调用内部类的构造器,这也说明了两者之间一定的独立性
附件:
http://hi.csdn.net/attachment/201105/25/0_1306308891WRxD.gif
http://hi.csdn.net/attachment/201105/25/0_1306308991G1Va.gif
下到自己电脑上之后把后缀改成rar就可以使用了,可以直接导入到eclipse中去