第十章 内部类

 

个人觉得大部分内部类都可以使用组合实现,具体使用组合还是内部类看需求而定,内部类可以隐藏细节,但隐藏也就很难重用

在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中去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值