《Java编程思想》之内部类——深奥而复杂

1、当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地(从实现某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类,实质上效果是一样得。)这是因为此内部类——某个接口的实现——对于其他人来说能够完全不可见,并且不可用。所得到的只是指向基类或接口的引用,所以能够很方便地隐藏实现细节

运行结果:


1).PContent是private的,所以除了Parcel,没有人能访问它。

2).Pdestination是protected,所以只有Parcel及其子类、还有与Parcel用包的类能访问。

3).这意味着,如果客户端程序员想了解或访问这些成员,那是要受限制的。

4).实际上,甚至不能向下转型成private内部类(或protected内部类,除非是继承自它的子类),因为不能访问其名字。

5).所以通过类似如上的方式,可以完全阻止任何依赖类型的编码,并且完全隐藏了实现的细节

6).此外,从客户端程序员的角度来看,由于不能访问(为什么?)任何新增加的、原本不属于公共接口的方法所以扩展接口是没有价值的。这也给Java编译器提供了生成更高效代码的机会。

7).以上是内部类的典型用途。

 

2、在一个方法或者任意的作用域内定义内部类的两个理由:

1).如前所示,你实现了某个类型的接口,于是可以创建并返回对其的引用。。

2).你要解决一个复杂的问题,想创建一个类来辅助你的解决方案,但是又不希望这个类是公共可用的。

3、局部内部类:在方法的作用域内(而不是在其他类的作用域内)创建一个完整的类。方法的执行完毕,并不意味该局部内部类就不可用了。另外,局部内部类不能有访问说明符。

4、匿名内部类

其上是下述形式的简化形式:

若匿名内部类需要一个有参数的构造器

5、匿名内部类没有命名的构造器,但通过实例初始化,能够达到为一个构造器的效果

运行结果:

 

6、匿名内部类中使用一个在外部定义的对象,那么编译器会要求其参数引用是final的。

7、Java的内部类,拥有其外围类的所有元素的访问权。(这与C++的嵌套类的设计非常不同,在C++中只是单纯的名字隐藏机制与外围对象没有联系,也没有隐含的访问权。)

这是如何做到的呢?

       当外围类的对象创建了一个内部类的对象时,此内部类对象必定会保存一个指向那个外围类对象的引用。在你访问外围类的成员的时候,就是那个“隐藏的”引用来选择外围类的成员。(构建内部类对象时,需要一个指向其外围类对象的引用,如果编译器访问不到这个引用就会报错。)

8、嵌套类:如果不需要内部类对象与其外围类对象之间的联系,那么可以将内部类声明为static。这通常称为嵌套类

1).要创建嵌套类的对象,并不需要其外围类的对象。

2).不能从嵌套类的对象中访问非静态外围对象。

9、普通内部类与嵌套类的区别:普通内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含所有这些东西。

10、普通内部类(非static)可以通过一个特殊的this引用可以链接到其外围类对象。嵌套类就没有这个特殊的this引用,这使得它类似一个static方法。

11、内部类的继承存在的问题:那个指向外围类对象的“秘密的”引用必须被初始化,而在导出类中不再存在可连接的缺省对象。例子如下:

       虽然是继承内部类,但是当生产一个构造器时,缺省的构造器并不算好,而且不能只是传递一个指向外围类对象的引用,必须在构造器内使用如下语法:

       outter.super();

这样才提供了必要的引用,然后程序才能编译通过。若缺省上面语句,会提示“由于某些中间构造函数调用,没有任何类型 Outter 的外层实例可用”的错误。

12、内部类的覆盖,比较俩个例子:

1).

运行结果

 

2).

运行结果:


下接《Java编程思想》之为什么需要内部类?

以上内容整理自《Java编程思想》,若有遗漏,请您不吝指出!


posted @ 2012-01-29 19:23  我的IT技术  阅读(330)  评论(0编辑  收藏  举报