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

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

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




  }  

  void cleanup() {  

    System。out。println(〃Erasing a Circle〃);  

    super。cleanup();  

  }  

}  

  

class Triangle extends Shape {  

  Triangle(int i) {  

    super(i);  

    System。out。println(〃Drawing a Triangle〃);  

  }  

  void cleanup() {  

    System。out。println(〃Erasing a Triangle〃);  

    super。cleanup();  

  }  

}  

  

class Line extends Shape {  

  private int start; end;  

  Line(int start; int end) {  

    super(start);  

    this。start = start;  

    this。end = end;  

    System。out。println(〃Drawing a Line: 〃 +  

           start + 〃; 〃 + end);  

  }  

  void cleanup() {  

    System。out。println(〃Erasing a Line: 〃 +  

           start + 〃; 〃 + end);  

    super。cleanup();  

  }  

}  

  

public class CADSystem extends Shape {  

  private Circle c;  

  private Triangle t;  

  private Line'' lines = new Line'10';  

  CADSystem(int i) {  

    super(i + 1);  

    for(int j = 0; j 《 10; j++)  

      lines'j' = new Line(j; j*j);  

    c = new Circle(1);  

    t = new Triangle(1);  

    System。out。println (〃bined constructor〃);  

  }  

  void cleanup() {  

    System。out。println(〃CADSystem。cleanup()〃);  

    t。cleanup();  

    c。cleanup();  



                                                                                             147 


…………………………………………………………Page 149……………………………………………………………

    for(int i = 0; i 《 lines。length; i++)  

      lines'i'。cleanup();  

    super。cleanup();  

  }  

  public static void main(String'' args) {  

    CADSystem x = new CADSystem(47);  

    try {  

      // Code and exception handling。。。  

    } finally {  

      x。cleanup();  

    }  

  }  

} ///:~  

  

这个系统中的所有东西都属于某种 Shape (几何形状)。Shape 本身是一种 Object (对象),因为它是从根 

类明确继承的。每个类都重新定义了Shape 的cleanup()方法,同时还要用 super 调用那个方法的基础类版 

本。尽管对象存在期间调用的所有方法都可负责做一些要求清除的工作,但对于特定的Shape 类——Circle 

 (圆)、Triangle (三角形)以及Line (直线),它们都拥有自己的构建器,能完成“作图”(draw )任 

务。每个类都有它们自己的cleanup()方法,用于将非内存的东西恢复回对象存在之前的景象。  

在main()中,可看到两个新关键字:try 和 finally。我们要到第9 章才会向大家正式引荐它们。其中,try 

关键字指出后面跟随的块(由花括号定界)是一个“警戒区”。也就是说,它会受到特别的待遇。其中一种 

待遇就是:该警戒区后面跟随的finally 从句的代码肯定会得以执行——不管try 块到底存不存在(通过违 

例控制技术,try 块可有多种不寻常的应用)。在这里,finally 从句的意思是“总是为 x 调用cleanup(), 

无论会发生什么事情”。这些关键字将在第9 章进行全面、完整的解释。  

在自己的清除方法中,必须注意对基础类以及成员对象清除方法的调用顺序——假若一个子对象要以另一个 

为基础。通常,应采取与C++编译器对它的“破坏器”采取的同样的形式:首先完成与类有关的所有特殊工 

作(可能要求基础类元素仍然可见),然后调用基础类清除方法,就象这儿演示的那样。  

许多情况下,清除可能并不是个问题;只需让垃圾收集器尽它的职责即可。但一旦必须由自己明确清除,就 

必须特别谨慎,并要求周全的考虑。  

  

1。 垃圾收集的顺序  

不能指望自己能确切知道何时会开始垃圾收集。垃圾收集器可能永远不会得到调用。即使得到调用,它也可 

能以自己愿意的任何顺序回收对象。除此以外,Java 1。0 实现的垃圾收集器机制通常不会调用 finalize()方 

法。除内存的回收以外,其他任何东西都最好不要依赖垃圾收集器进行回收。若想明确地清除什么,请制作 

自己的清除方法,而且不要依赖finalize()。然而正如以前指出的那样,可强迫Java1。1 调用所有收尾模块 

 (Finalizer)。  



6。3。2  名字的隐藏  



只有C++程序员可能才会惊讶于名字的隐藏,因为它的工作原理与在 C++里是完全不同的。如果 Java 基础类 

有一个方法名被“过载”使用多次,在衍生类里对那个方法名的重新定义就不会隐藏任何基础类的版本。所 

以无论方法在这一级还是在一个基础类中定义,过载都会生效:  

  

//: Hide。java  

// Overloading a base…class method name  

// in a derived class does not hide the  

// base…class versions  

  

class Homer {  

  char doh(char c) {  

    System。out。println(〃doh(char)〃);  

    return 'd' ;  

  }  



                                                                                    148 


…………………………………………………………Page 150……………………………………………………………

  float doh(float f) {  

    System。out。println(〃doh(float)〃);  

    return 1。0f;  

  }  

}  

  

class Milhouse {}  

  

class Bart extends Homer {  

  void doh(Milhouse m) {}  

}  

  

class Hide {  

  public static void main(String'' args) {  

    Bart b = new Bart();  

    b。doh (1); // doh(float) used  

    b。doh('x');  

    b。doh(1。0f);  

    b。doh(new Milhouse());  

  }  

} ///:~  

  

正如下一章会讲到的那样,很少会用与基础类里完全一致的签名和返回类型来覆盖同名的方法,否则会使人 

感到迷惑(这正是 C++不允许那样做的原因,所以能够防止产生一些不必要的错误)。  



6。4 到底选择合成还是继承  



无论合成还是继承,都允许我们将子对象置于自己的新类中。大家或许会奇怪两者间的差异,以及到底该如 

何选择。  

如果想利用新类内部一个现有类的特性,而不想使用它的接口,通常应选择合成。也就是说,我们可嵌入一 

个对象,使自己能用它实现新类的特性。但新类的用户会看到我们已定义的接口,而不是来自嵌入对象的接 

口。考虑到这种效果,我们需在新类里嵌入现有类的private 对象。  

有些时候,我们想让类用户直接访问新类的合成。也就是说,需要将成员对象的属性变为public。成员对象 

会将自身隐藏起来,所以这是一种安全的做法。而且在用户知道我们准备合成一系列组件时,接口就更容易 

理解。car (汽车)对象便是一个很好的例子:  

  

//: Car。java  

// position with public objects  

  

class Engine {  

  public void start() {}  

  public void rev() {}  

  public void stop() {}  

}  

  

class Wheel {  

  public void inflate(int psi) {}  

}  

  

class Window {  

  public void rollup() {}  

  public void rolldown() {}  

}  



                                                                                             149 


…………………………………………………………Page 151……………………………………………………………

  

class Door {  

  public Window window = new Window();  

  public void open() {}  

  public void close() {}  

}  

  

public class Car {  

  public Engine engine = new Engine();  

  public Wheel'' wheel = new Wheel'4';  

  public Door left = new Door();  

       right = new Door(); // 2…door  

  Car() {  

    for(int i = 0; i 《 4; i++)  

      wheel'i' = new Wheel();  

  }  

  public static void main(String'' args) {  

    Car car = new Car();  

    car。left。window。rollup();  

    car。wheel'0'。inflate(72);  

  }  

} ///:~  

  

由于汽车的装配是故障分析时需要考虑的一项因素(并非只是基础设计简单的一部分),所以有助于客户程 

序员理解如何使用类,而且类创建者的编程复杂程度也会大幅度降低。  

如选择继承,就需要取得一个现成的类,并制作它的一个特殊版本。通常,这意味着我们准备使用一个常规 

用途的类,并根据特定的需求对其进行定制。只需稍加想象,就知道自己不能用一个车辆对象来合成一辆汽 

车——汽车并不“包含”车辆;相反,它“属于”车辆的一种类别。“属于”关系是用继承来表达的,而 

 “包含”关系是用合成来表达的。  



6。5 protected  



现在我们已理解了继承的概念,protected 这个关键字最后终于有了意义。在理想情况下,private 成员随时 

都是“私有”的,任何人不得访问。但在实际应用中,经常想把某些东西深深地藏起来,但同时允许访问衍 

生类的成员。protected 关键字可帮助我们做到这一点。它的意思是“它本身是私有的,但可由从这个类继 

承的任何东西或者同一个包内的其他任何东西访问”。也就是说,Java 中的protected 会成为进入“友好” 

状态。  

我们采取的最好的做法是保持成员的private 状态——无论如何都应保留对基 础的实施细节进行修改的权 

利。在这一前提下,可通过protected 方法允许类的继承者进行受到控制的访问:  

  

//: Orc。java  

// The protected keyword  

import java。util。*;  

  

class Villain {  

  private int i;  

  protected int read() { return i; }  

  protected void set(int ii) { i = ii; }  

  public Villain(int ii) { i = ii; }  

  public int value(int m) { return m*i; }  

}  

  

public class Orc extends Villain {  



                        
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!