你已经知道你想要的机械装置的名字了-
generics
!
abstract class AbstractEvent {
// Insert fields/methods common for all events here
}
没什么奇怪的。接下来,创建一个参数化的监听器类/接口,并为其类型参数指定事件对象类的上限:
interface Listener<T extends AbstractEvent> {
void process(T event);
}
现在,您可以继续创建特定的事件类:
class PonyEvent extends AbstractEvent {
// Pony-specific stuff goes here
}
而且,好吧,这应该是你所需要的。继续并实现侦听器类:
class LoggingPonyListener implements Listener<PonyEvent> {
@Override
public void process(PonyEvent event){
System.out.println("Pony event occurred: " + event);
}
}
现在,您可能很想编写这样一个通用事件调度类:
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<T>> listeners =
new CopyOnWriteArrayList<Listener<T>>();
public void addListener(Listener<T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<T> listener : listeners)
listener.process(event);
}
}
看起来很可爱,嗯?你可以这样做:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new LoggingPonyListener());
dispatcher.dispatchEvent(new PonyEvent());
这些东西,当我们用过之后,
继续重复使用
不是真的认为你很棒
EventDispatcher
class DebugListener implements Listener<AbstractEvent> {
private final String msg;
public DebugListener(String msg) { this.msg = msg; }
@Override
public void process(AbstractEvent event){
System.out.println(msg);
}
}
这应该是可重复使用的,对吗?不,这样不行:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new DebugListener("pony event"));
DebugListener
是一个
Listener<AbstractEvent>
Listener<PonyEvent>
. 解决此问题的方法是对参数类型使用下限:
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<? super T>> listeners =
new CopyOnWriteArrayList<Listener<? super T>>();
public void addListener(Listener<? super T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<? super T> listener : listeners)
listener.process(event);
}
}
这给了你想要的行为:就像你可以发送一个
PonyEvent
到
process
a方法
侦听器<AbstractEvent>
(因为
是一个
AbstractEvent
),现在可以使用使用类型参数化的事件调度程序类来激发使用其超类型之一参数化的侦听器。