当前位置:天才代写 > tutorial > JAVA 教程 > 抽象的应用

抽象的应用

2017-11-13 08:00 星期一 所属: JAVA 教程 浏览:440

走到这一步,接下来该思量一下设计方案剩下的部门了——在那边利用类?既然归类到垃圾箱的步伐很是不雅且过于袒露,为什么不断绝谁人进程,把它埋没到一个类里呢?这就是著名的“假如必需做不雅的工作,至少应将其当地化到一个类里”法则。看起来就象下面这样:

抽象的应用

此刻,只要一种新范例的Trash插手要领,对TrashSorter工具的初始化就必需变换。可以想象,TrashSorter类看起来应该象下面这个样子:
class TrashSorter extends Vector {
void sort(Trash t) { /* … */ }
}
也就是说,TrashSorter是由一系列句柄组成的Vector(系列),而那些句柄指向的又是由Trash句柄组成的Vector;操作addElement(),可以安装新的TrashSorter,如下所示:
TrashSorter ts = new TrashSorter();
ts.addElement(new Vector());
可是此刻,sort()却成为一个问题。用静态方法编码的要领如何应付一种新范例插手的事实呢?为办理这个问题,必需从sort()里将范例信息删除,使其需要做的所有工作就是挪用一个通用要领,用它顾问涉及范例处理惩罚的所有细节。这虽然是对一个动态绑定要领举办描写的另一种方法。所以sort()会在序列中简朴地遍历,并为每个Vector都挪用一个动态绑定要领。由于这个要领的任务是收集它感乐趣的垃圾片,所以称之为grab(Trash)。布局此刻酿成了下面这样:

抽象的应用

个中,TrashSorter需要挪用每个grab()要领;然后按照当前Vector容纳的是什么范例,会得到一个差异的功效。也就是说,Vector必需寄望本身容纳的范例。办理这个问题的传统要领是建设一个基本“Trash bin”(垃圾筒)类,并为但愿容纳的每个差异的范例都担任一个新的衍生类。若Java有一个参数化的范例机制,那就也许是最直接的要领。但对付这种机制应该为我们构建的各个类,我们不该该举办贫苦的手工编码,今后的“调查”方法提供了一种更好的编码方法。
OOP设计一条根基的准则是“为状态的变革利用数据成员,为行为的变革利用多性形”。对付容纳Paper(纸张)的Vector,以及容纳Glass(玻璃)的Vector,各人最开始或者会认为别离用于它们的grab()要领必定会发生差异的行为。但详细如何却完全取决于范例,而不是其他什么对象。可将其表明成一种差异的状态,并且由于Java有一个类可暗示范例(Class),所以可用它判定特定的Tbin要容纳什么范例的Trash。
用于Tbin的构建器要求我们为其通报本身选择的一个Class。这样做可汇报Vector它但愿容纳的是什么范例。随后,grab()要领用Class BinType和RTTI来查抄我们通报给它的Trash工具是否与它但愿收集的范例相符。
下面列出完整的办理方案。设定为注释的编号(如*1*)便于各人比较措施后头列出的说明。

 

//: RecycleB.java
// Adding more objects to the recycling problem
package c16.recycleb;
import c16.trash.*;
import java.util.*;

// A vector that admits only the right type:
class Tbin extends Vector {
  Class binType;
  Tbin(Class binType) { 
    this.binType = binType; 
  }
  boolean grab(Trash t) {
    // Comparing class types:
    if(t.getClass().equals(binType)) {
      addElement(t);
      return true; // Object grabbed
    }
    return false; // Object not grabbed
  }
}

class TbinList extends Vector { //(*1*)
  boolean sort(Trash t) {
    Enumeration e = elements();
    while(e.hasMoreElements()) {
      Tbin bin = (Tbin)e.nextElement();
      if(bin.grab(t)) return true;
    }
    return false; // bin not found for t
  }
  void sortBin(Tbin bin) { // (*2*)
    Enumeration e = bin.elements();
    while(e.hasMoreElements())
      if(!sort((Trash)e.nextElement()))
        System.out.println("Bin not found");
  }
}

public class RecycleB {
  static Tbin bin = new Tbin(Trash.class);
  public static void main(String[] args) {
    // Fill up the Trash bin:
    ParseTrash.fillBin("Trash.dat", bin);

    TbinList trashBins = new TbinList();
    trashBins.addElement(
      new Tbin(Aluminum.class));
    trashBins.addElement(
      new Tbin(Paper.class));
    trashBins.addElement(
      new Tbin(Glass.class));
    // add one line here: (*3*)
    trashBins.addElement(
      new Tbin(Cardboard.class));

    trashBins.sortBin(bin); // (*4*)

    Enumeration e = trashBins.elements();
    while(e.hasMoreElements()) {
      Tbin b = (Tbin)e.nextElement();
      Trash.sumValue(b);
    }
    Trash.sumValue(bin);
  }
} ///:~

(1) TbinList容纳一系列Tbin句柄,所以在查找与我们通报给它的Trash工具相符的环境时,sort()能通过Tbin担任。
(2) sortBin()答允我们将一个完整的Tbin通报进去,并且它会在Tbin里遍历,挑选出每种Trash,并将其归类到特定的Tbin中。请留意这些代码的通用性:新范例插手时,它自己不需要任何窜改。只要新范例插手(或产生其他事件)时大量代码都不需要变革,就表白我们设计的是一个容易扩展的系统。
(3) 此刻可以体会添加新范例有何等容易了。为支持添加,只需要窜改几行代码。如确实有须要,甚至可以进一步地改造设计,使更多的代码都保持“牢靠”。
(4) 一个要领挪用使bin的内容归类到对应的、特定范例的垃圾筒里。

 

    关键字:

天才代写-代写联系方式