源程序的如下://: c08:controller:Controller.java
// From 'Thinking in Java, 2nd ed.' by Bruce Eckel
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
// Along with Event, the generic
// framework for all control systems:
package c08.controller;// This is just a way to hold Event objects.
class EventSet {
  private Event[] events = new Event[100];
  private int index = 0;
  private int next = 0;
  public void add(Event e) {
    if(index >= events.length)
      return; // (In real life, throw exception)
    events[index++] = e;
  }
  public Event getNext() {
    boolean looped = false;
    int start = next;
    do {
      next = (next + 1) % events.length;
      // See if it has looped to the beginning:
      if(start == next) looped = true;
      // If it loops past start, the list 
      // is empty:
      if((next == (start + 1) % events.length)
         && looped)
        return null;
    } while(events[next] == null);
    return events[next];
  }
  public void removeCurrent() {
    events[next] = null;
  }
}public class Controller {
  private EventSet es = new EventSet();
  public void addEvent(Event c) { es.add(c); }
  public void run() {
    Event e;
    while((e = es.getNext()) != null ) {
      if(e.ready()) {
        e.action();
        System.out.println(e.description());
        es.removeCurrent();
      }
    }
  }
} ///:~为什么在public class Controller{ }中 e.action();可以被调用啊,它不是abstract 类型的吗?
如果改成这样:  public class Controller {
  private EventSet es = new EventSet();
  public void addEvent(Event c) { es.add(c); }
  public void run() {
    Event e;
    e.action();
   }
} ///:~怎么又通不过编译了,这是为什么啊!

解决方案 »

  1.   

    因为public class Controller中
    e=es.getNext().这是从容器中取出来的.编译器并不知道这是一个abstract 的event 还是一个他的具体的子类,所以编译就通过了,运行时,如果取出的是个abstract 的event,它在运行时也是要报错的
    而你改写的代码中e就是一个虚拟类.编译器知道这点.所以不允许调用.而且还没有初始化,肯定通不过编译.
      

  2.   

    在上面的例子中,Event的原始代码是:
    //: c08:controller:Event.java
    // From 'Thinking in Java, 2nd ed.' by Bruce Eckel
    // www.BruceEckel.com. See copyright notice in CopyRight.txt.
    // The common methods for any control event.
    package c08.controller;abstract public class Event {
      private long evtTime;
      public Event(long eventTime) {
        evtTime = eventTime;
      }
      public boolean ready() {
        return System.currentTimeMillis() >= evtTime;
      }
      abstract public void action();
      abstract public String description();
    } ///:~