友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第98章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




是安全的;基础类不可能再拥有一个比衍生类更大的接口。因此,我们通过基础类接口发送的每一条消息都 

肯定能够接收到。但在进行下溯造型的时候,我们(举个例子来说)并不真的知道一个几何形状实际是一个 

圆,它完全可能是一个三角形、方形或者其他形状。  

  



                                                                             206 


…………………………………………………………Page 208……………………………………………………………

                                                  

  

为解决这个问题,必须有一种办法能够保证下溯造型正确进行。只有这样,我们才不会冒然造型成一种错误 

的类型,然后发出一条对象不可能收到的消息。这样做是非常不安全的。  

在某些语言中(如 C++),为了进行保证“类型安全”的下溯造型,必须采取特殊的操作。但在Java 中,所 

有造型都会自动得到检查和核实!所以即使我们只是进行一次普通的括弧造型,进入运行期以后,仍然会毫 

无留情地对这个造型进行检查,保证它的确是我们希望的那种类型。如果不是,就会得到一个 

ClassCastException (类造型违例)。在运行期间对类型进行检查的行为叫作“运行期类型标识” 

 (RTTI )。下面这个例子向大家演示了RTTI 的行为:  

  

//: RTTI。java  

// Downcasting & Run…Time Type  

// Identification (RTTI)  

import java。util。*;  

  

class Useful {  

  public void f() {}  

  public void g() {}  

}  

  

class MoreUseful extends Useful {  

  public void f() {}  

  public void g() {}  

  public void u() {}  

  public void v() {}  

  public void w() {}  

}  

  

public class RTTI {  

  public static void main(String'' args) {  

    Useful'' x = {  

      new Useful();  

      new MoreUseful()  

    };  

    x'0'。f();  

    x'1'。g();  

    // pile…time: method not found in Useful:  



                                                                                             207 


…………………………………………………………Page 209……………………………………………………………

    //! x'1'。u();  

    ((MoreUseful)x'1')。u(); // Downcast/RTTI  

    ((MoreUseful)x'0')。u(); // Exception thrown  

  }  

} ///:~  

  

和在示意图中一样,MoreUseful (更有用的)对Useful (有用的)的接口进行了扩展。但由于它是继承来 

的,所以也能上溯造型到一个Useful。我们可看到这会在对数组x (位于main()中)进行初始化的时候发 

生。由于数组中的两个对象都属于 Useful 类,所以可将 f()和g()方法同时发给它们两个。而且假如试图调 

用u() (它只存在于MoreUseful),就会收到一条编译期出错提示。  

若想访问一个MoreUseful 对象的扩展接口,可试着进行下溯造型。如果它是正确的类型,这一行动就会成 

功。否则,就会得到一个ClassCastException 。我们不必为这个违例编写任何特殊的代码,因为它指出的是 

一个可能在程序中任何地方发生的一个编程错误。  

RTTI 的意义远不仅仅反映在造型处理上。例如,在试图下溯造型之前,可通过一种方法了解自己处理的是什 

么类型。整个第 11章都在讲述 Java 运行期类型标识的方方面面。  



7。9 总结  



 “多形性”意味着“不同的形式”。在面向对象的程序设计中,我们有相同的外观(基础类的通用接口)以 

及使用那个外观的不同形式:动态绑定或组织的、不同版本的方法。  

通过这一章的学习,大家已知道假如不利用数据抽象以及继承技术,就不可能理解、甚至去创建多形性的一 

个例子。多形性是一种不可独立应用的特性(就象一个 switch 语句),只可与其他元素协同使用。我们应将 

其作为类总体关系的一部分来看待。人们经常混淆 Java 其他的、非面向对象的特性,比如方法过载等,这些 

特性有时也具有面向对象的某些特征。但不要被愚弄:如果以后没有绑定,就不成其为多形性。  

为使用多形性乃至面向对象的技术,特别是在自己的程序中,必须将自己的编程视野扩展到不仅包括单独一 

个类的成员和消息,也要包括类与类之间的一致性以及它们的关系。尽管这要求学习时付出更多的精力,但 

却是非常值得的,因为只有这样才可真正有效地加快自己的编程速度、更好地组织代码、更容易做出包容面 

广的程序以及更易对自己的代码进行维护与扩展。  



7。10 练习  



(1) 创建Rodent (啮齿动物):Mouse (老鼠);Gerbil (鼹鼠);Hamster (大颊鼠)等的一个继承分级结 

构。在基础类中,提供适用于所有 Rodent 的方法,并在衍生类中覆盖它们,从而根据不同类型的Rodent 采 

取不同的行动。创建一个Rodent 数组,在其中填充不同类型的 Rodent,然后调用自己的基础类方法,看看 

会有什么情况发生。  

(2) 修改练习 1,使Rodent 成为一个接口。  

(3) 改正WindError。java 中的问题。  

(4) 在GreenhouseControls。java 中,添加Event 内部类,使其能打开和关闭风扇。  



                                                                       208 


…………………………………………………………Page 210……………………………………………………………

                       第 8 章 对象的容纳  



  

 “如果一个程序只含有数量固定的对象,而且已知它们的存在时间,那么这个程序可以说是相当简单的。”  

  

通常,我们的程序需要根据程序运行时才知道的一些标准创建新对象。若非程序正式运行,否则我们根本不 

知道自己到底需要多少数量的对象,甚至不知道它们的准确类型。为了满足常规编程的需要,我们要求能在 

任何时候、任何地点创建任意数量的对象。所以不可依赖一个已命名的句柄来容纳自己的每一个对象,就象 

下面这样:  

MyObject myHandle;  

因为根本不知道自己实际需要多少这样的东西。  

为解决这个非常关键的问题,Java 提供了容纳对象(或者对象的句柄)的多种方式。其中内建的类型是数 

组,我们之前已讨论过它,本章准备加深大家对它的认识。此外,Java 的工具(实用程序)库提供了一些 

 “集合类”(亦称作“容器类”,但该术语已由AWT 使用,所以这里仍采用“集合”这一称呼)。利用这些 

集合类,我们可以容纳乃至操纵自己的对象。本章的剩余部分会就此进行详细讨论。  



8。1 数组  



对数组的大多数必要的介绍已在第 4 章的最后一节进行。通过那里的学习,大家已知道自己该如何定义及初 

始化一个数组。对象的容纳是本章的重点,而数组只是容纳对象的一种方式。但由于还有其他大量方法可容 

纳数组,所以是哪些地方使数组显得如此特别呢?  

有两方面的问题将数组与其他集合类型区分开来:效率和类型。对于Java 来说,为保存和访问一系列对象 

 (实际是对象的句柄)数组,最有效的方法莫过于数组。数组实际代表一个简单的线性序列,它使得元素的 

访问速度非常快,但我们却要为这种速度付出代价:创建一个数组对象时,它的大小是固定的,而且不可在 

那个数组对象的“存在时间”内发生改变。可创建特定大小的一个数组,然后假如用光了存储空间,就再创 

建一个新数组,将所有句柄从旧数组移到新数组。这属于“矢量”(Vector)类的行为,本章稍后还会详细 

讨论它。然而,由于为这种大小的灵活性要付出较大的代价,所以我们认为矢量的效率并没有数组高。  

C++的矢量类知道自己容纳的是什么类型的对象,但同 Java 的数组相比,它却有一个明�
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!