- 1、本文档共16页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第十一章 运行期类型鉴定
第 11章 运行期类型鉴定
运行期类型鉴定(RTTI)的概念初看非常简单——手上只有基础类型的一个句柄时,利用它判断一个对象的
正确类型。
然而,对RTTI的需要暴露出了面向对象设计许多有趣(而且经常是令人困惑的)的问题,并把程序的构造问
题正式摆上了桌面。
本章将讨论如何利用Java在运行期间查找对象和类信息。这主要采取两种形式:一种是“传统”RTTI,它假
定我们已在编译和运行期拥有所有类型;另一种是Java1.1特有的“反射”机制,利用它可在运行期独立查
找类信息。首先讨论“传统”的RTTI,再讨论反射问题。
11.1对 RTTI的需要
请考虑下面这个熟悉的类结构例子,它利用了多形性。常规类型是Shape类,而特别衍生出来的类型是
Circle,Square和Triangle。
这是一个典型的类结构示意图,基础类位于顶部,衍生类向下延展。面向对象编程的基本目标是用大量代码
控制基础类型(这里是Shape)的句柄,所以假如决定添加一个新类(比如Rhomboid,从Shape衍生),从
而对程序进行扩展,那么不会影响到原来的代码。在这个例子中,Shape接口中的动态绑定方法是draw(),
所以客户程序员要做的是通过一个普通Shape句柄调用draw()。draw()在所有衍生类里都会被覆盖。而且由
于它是一个动态绑定方法,所以即使通过一个普通的Shape句柄调用它,也有表现出正确的行为。这正是多
形性的作用。
所以,我们一般创建一个特定的对象(Circle,Square,或者Triangle),把它上溯造型到一个Shape(忽
略对象的特殊类型),以后便在程序的剩余部分使用匿名Shape句柄。
作为对多形性和上溯造型的一个简要回顾,可以象下面这样为上述例子编码(若执行这个程序时出现困难,
请参考第3章3.1.2小节“赋值”):
//: Shapes.java
package c11;
importjava.util.*;
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println(Circle.draw());
}
}
class Square implements Shape {
333
public void draw() {
System.out.println(Square.draw());
}
}
class Triangle implements Shape {
public void draw() {
System.out.println(Triangle.draw());
}
}
public class Shapes {
public static void main(String[] args) {
Vector s = new Vector();
s.addElement(new Circle());
s.addElement(new Square());
s.addElement(new Triangle());
Enumeration e = s.elements();
while(e.hasMoreElements())
((Shape)e.nextElement()).draw();
}
} ///:~
基础类可编码成一个interface(接口)、一个abstract(抽象)类或者一个普通类。由于Shape没有真正
的成员(亦即有定义的成员),而且并不在意我们创建了一个纯粹的Shape对象,所以最适合和最灵活的表
达方式便是用一个接口。而且由于不必设置所有那些abstract关键字,所以整个代码也显得更为清爽。
每个衍生类都覆盖了基础类draw方法,所以具有不同的行为。在main()中创建了特定类型的Shape,然后将
其添加到一个Vector。这里正是上溯造型发生的地方,因为Vector只容纳了对象。由于Java中的所有东西
(除基本数据类型外)都是对象,所以Vector也能容纳Shape对象。但在上溯造型至Object的过程中,任
何特殊
文档评论(0)