【发布时间】:2009-11-01 23:04:20
【问题描述】:
我正在学习 Java,我想将我的课程变成一个可观察的课程。
但是我已经让它扩展了另一个类。
我该怎么办?
【问题讨论】:
标签: java
我正在学习 Java,我想将我的课程变成一个可观察的课程。
但是我已经让它扩展了另一个类。
我该怎么办?
【问题讨论】:
标签: java
我建议完全避免使用Observable 类,而是定义特定于事件的侦听器和相应的事件定义。然后在您的类中定义一个侦听器列表以及添加和删除侦听器的方法,并将事件传播给它们(见下文)。
Observable 强制您使用java.lang.Object 表示事件,然后使用instanceof 检查事件类型,这是一种丑陋的非OO 方法,并且使代码更难理解。如果您查看 javax.swing 包中的类,您会发现它们完全避免使用 Observer / Observable 并使用类似于以下的方法。
事件定义
public class MyChangeEvent extends EventObject {
// This event definition is stateless but you could always
// add other information here.
public MyChangeEvent(Object source) {
super(source);
}
}
监听器定义
public interface MyChangeListener {
public void changeEventReceived(MyChangeEvent evt);
}
类定义
public class MyClass {
// Use CopyOnWriteArrayList to avoid ConcurrentModificationExceptions if a
// listener attempts to remove itself during event notification.
private final CopyOnWriteArrayList<MyChangeListener> listeners;
public class MyClass() {
this.listeners = new CopyOnWriteArrayList<MyChangeListener>();
}
public void addMyChangeListener(MyChangeListener l) {
this.listeners.add(l);
}
public void removeMyChangeListener(MyChangeListener l) {
this.listeners.remove(l);
}
// Event firing method. Called internally by other class methods.
protected void fireChangeEvent() {
MyChangeEvent evt = new MyChangeEvent(this);
for (MyChangeListener l : listeners) {
l.changeEventReceived(evt);
}
}
}
【讨论】:
Java 不允许多重继承,因此没有直接的方法可以做到这一点。您应该考虑使用委托模式,让您的主要对象将他的观察者行为委托给另一个对象..
class YourObject extends ItsAncestorClass
{
private Observer includedObserver;
public Observer getHisObserver(..)
}
另一种方法是将您的类从中扩展的对象转换为接口,然后您将被允许从 Observer 扩展。
【讨论】:
另一种选择是将对象包装在 Observable 对象中。
public class MyObjectObservableWrapper implements Observable {
private MyObject myObject;
public MyObjectObservaleWrapper(MyObject myObject){
this.myObject = myObject;
}
// interface methods here
}
当 Observable 方法使用的数据可以通过 MyObject 的公共方法访问时,此选项有效。因此,它可能并不适合所有情况。
【讨论】:
多重继承(扩展两个类)在 Java 中是不可能的。几乎在所有情况下都被认为是糟糕的设计。
如果您提供更多信息,也许有人可以为您提供更多帮助。
【讨论】:
您可以扩展 Observable 并将原始父级包装在您的可观察子类中。将所有方法调用委托给被包装的对象。
【讨论】:
使用桥梁。
创建一个扩展 Observable 的类,第一个类只调用第二个类的方法。
桥接方法详解:
public class XXX {
public class XXXObservableBridge : Observable {
public void RaiseEvent();
// Listeners etc
}
private XXXObservableBridge ObservableBridge;
XXX() {
ObservableBridge = new ObservableBridge;
}
public Observable AsObservable() { return ObservableBidge; }
public void RaiseEvent() { ObservableBridge.RaiseEvent(); }
}
【讨论】: