- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第十章类型检查.
第十章 类型检查
运行期类型识别(RTTI,run-time type identification)的概念初看起来非常简单:当你只有一个指向对象的基类的引用时,RTTI 机制可以让你找出这个对象确切的类型。对 RTTI的需要,揭示了面向对象设计中许多有趣(并且复杂)的问题,同时也提出了如何组织程序的问题。
本章将讨论 Java是如何允许我们在运行期识别对象和类的信息。主要有两种方式:一种是传统的 RTTI,它假定我们在编译期和运行期已经知道了所有的类型;另一种是“反射机制(reflection)”,它允许我们在运行期获得类的信息。我们先讨论 “传统”的 RTTI,再讨论反射。
为什么需要 RTTI
让我们来思考已经很熟悉了的一个使用了多态的类层次结构的例子。最一般化的类型是基类
Shape,而派生出的具体类有 Circle,Square和 Triangle。
这是一个典型的类层次结构图,基类位于顶部,派生类向下扩展。面向对象编程基本的目的
是:你的代码只操纵对基类(这里是 Shape)的引用。这样,如果你要添加一个新类(比
如从 Shape派生 Rhomboid)来扩展程序,就不会影响到原来的代码。在这个例子的 Shape
接口中动态绑定了 draw方法,目的就是让客户端程序员使用一般化的 Shape的引用来调用 draw。draw在所有派生类里都会被重载,并且由于它是被动态绑定的,所以即使是通过通用的 Shape引用来调用,也能产生正确行为。这就是多态( polymorphism)。
因此,我们通常会创建一个特定的对象( Circle,Square,或者 Triangle),把它向上转型成 Shape(忽略对象的特定类型),并在后面的程序中使用匿名(译注:即不知道具体类型)的 Shape引用。
简要复习一下多态和向上类型转换,并为上面的例子编码:
//: c10:Shapes.java
import com.bruceeckel.simpletest.*;
class Shape
void draw System.out.printlnthis + .draw;class Circle extends Shape
public String toString return Circle;class Square extends Shape
public String toString return Square;class Triangle extends Shape
public String toString return Triangle;public class Shapes
private static Test monitor new Test;
public static void mainString[] args
// Array of Object, not Shape:
Object[] shapeListnew Circle,
new Square,
new Triangle
;
forint i 0; i shapeList.length; i++
ShapeshapeList[i].draw; // Must cast
monitor.expectnew String[]
Circle.draw,
Square.draw,
Triangle.draw
;///:~
基类中包含 draw方法,它通过传递 this参数给 System.out.println,间接地使用 toString打印类标识符。如果是某个对象调用这个方法,它会自动调用 toString生成字符串。每个派生类都要重载(从 Object类继承来的)toString方法,这样 draw在不同情况下就打印出不同的消息。
在 main中,生成了各种特定类型的 Shape,并加入到数组中。这个数组有点特别,因为它不是一个 Shape的数组(虽然它可以是),而是根类 Object类的对象的数组。这样做的原因是为第十一章作准备,我们将学习 collection工具(也被称作容器container),它唯一的工作是保存与管理对象。基于通用性的考虑,这些collection应该能保存任何类型的对象,因此它们保存根类 Object类的对象。Object类的数组引出了我们将在第十一章 Collection中学习的一个重要的问题。
在这个例子中,当把 Shape对象放入 Object类的数组时会向上转型。由于在 Java中所有的对象都是根类 Object类的对象(除了基本类型),所以一个 Object的数组自然能保存
Shap
原创力文档


文档评论(0)