16.10 Observable (观测) Observable类用于创建可以观测到你的程序中其他部分的子类。当这种子类的对象发生变化时,观测类被通知。观测类必须实现定义了update( )方法的Observer接口。当一个观测程序被通知到一个被观测对象的改变时,update( )方法被调用。Observable定义了表16-7中的方法。一个被观测的对象必须服从下面的两个简单规则。第一,如果它被改变了,它必须调用setChanged( )方法。第二,当它准备通知观测程序它的改变时,它必须调用notifyObservers( )方法。这导致了在观测对象中对update( )方法的调用。注意—_________—当对象在调用otifyObservers( )方法之前,没有调用setChanged( )方法,就不会有什么动作发生。在update( )被调用之前,被观测对象必须调用setChanged( ) 和notifyObservers( )两种方法。 表16-7 由Observable 定义的方法 方法 描述 void addObserver(Observer obj) 将obj增加到观测调用对象的对象列表中 protected void clearChanged( ) 调用该方法返回调用对象的状态为“未改变的” int countObservers( ) 返回观测调用对象的对象的个数 void deleteObserver(Observer obj) 从观测调用对象的对象列表中删除obj void deleteObservers( ) 删除对调用对象的所有观测程序 boolean hasChanged( ) 如果调用对象已经被改变了,则返回true;如果它没有被改变,则返回false void notifyObservers( ) 通过调用update( )方法,将调用对象的改变通知其所有观测程序。 null被传递给update( )方法作为其第二个参数 void notifyObservers(Object obj) 通过调用update( )方法,将调用对象的改变通知其所有观测程序。 obj被传递给update( )方法作为其第二个参数 protected void setChanged( ) 当调用对象发生改变时被调用 注意notifyObservers()有两种形式:一种带有参数而另一种没有。当用参数调用notifyObservers( )方法时,该对象被传给观测程序的update( )方法作为其第二个参数。否则,将给update( )方法传递一个null。可以使用第二个参数传递适合于你的应用程序的任何类型的对象。 16.10.1 观测接口 为了观测一个可观测的对象,必须实现Observer接口。这个接口仅仅定义了如下所示的一个方法。 void update(Observable observOb, Object arg) 这里,observOb是被观测的对象,而arg是由notifyObservers( )方法传递的值。当被观测对象发生了改变,调用update( )方法。 16.10.2 观测程序举例 这里是一个说明可观测对象的例子。该程序创建了一个叫做Watcher的类,该类实现了Observer接口。被监控的类叫做BeingWatched,它扩展了Observable。在BeingWatched里,是counter( )方法,该方法仅是从一个指定的值开始递减计数。它使用sleep( )方法在两次计数中间等待十分之一秒。每次计数改变时,notifyObservers( )方法被调用,而当前的计数被作为参数传递给notifyObservers( )方法。这导致了Watcher中的update( )方法被调用,显示当前的计数值。在main( )内,分别调用observing和observed的Watcher和BeingWatched对象被创建。然后,observing被增加到对observed的观测程序列表。这意味着每次counter( )调用notifyObservers( )方法时,observing.update( )方法将被调用。 /* Demonstrate the Observable class and the Observer interface. */ import java.util.*; // This is the observing class. class Watcher implements Observer { public void update(Observable obj, Object arg) { System.out.println("update() called, count is " + ((Integer)arg).intValue()); } } / This is the class being observed. class BeingWatched extends Observable { void counter(int period) { for( ; period >=0; period--) { setChanged(); notifyObservers(new Integer(period)); try { Thread.sleep(100); } catch(InterruptedException e) { System.out.println("Sleep interrupted"); } } } } class ObserverDemo { public static void main(String args[]) { BeingWatched observed = new BeingWatched(); Watcher observing = new Watcher(); /* Add the observing to the list of observers for observed object. */ observed.addObserver(observing); observed.counter(10); } } 该程序的输出如下所示: update() called, count is 10 update() called, count is 9 update() called, count is 8 update() called, count is 7 update() called, count is 6 update() called, count is 5 update() called, count is 4 update() called, count is 3 update() called, count is 2 update() called, count is 1 update() called, count is 0 有多个对象可以用作观测程序。例如下面程序实现了两个观测类并且将每个类中的一个对象增加到BeingWatched观测程序列表中。第二个观测程序等待直到计数为0,随后振铃。 /* An object may be observed by two or more observers. */ import java.util.*; // This is the first observing class. class Watcher1 implements Observer { public void update(Observable obj, Object arg) { System.out.println("update() called, count is " + ((Integer)arg).intValue()); } } // This is the second observing class. class Watcher2 implements Observer { public void update(Observable obj, Object arg) { // Ring bell when done if(((Integer)arg).intValue() == 0) System.out.println("Done" + '\7'); } } // This is the class being observed. class BeingWatched extends Observable { void counter(int period) { for( ; period >=0; period--) { setChanged(); notifyObservers(new Integer(period)); try { Thread.sleep(100); } catch(InterruptedException e) { System.out.println("Sleep interrupted"); } } } } class TwoObservers { public static void main(String args[]) { BeingWatched observed = new BeingWatched(); Watcher1 observing1 = new Watcher1(); Watcher2 observing2 = new Watcher2(); // add both observers observed.addObserver(observing1); observed.addObserver(observing2); observed.counter(10); } } Observable类和Observer接口允许实现基于文档/视图方法的高级程序结构。它们也适用于多线程情况。
<<上一页
1
2
3
4
5
6
下一页>>
|