Flu*_*ffy 3 java oop generics inheritance
我有一个抽象类AbstractEvent和一些扩展它的"真正"类.我想AbstractListener用一个方法创建一个抽象类,process(??? event)这样AbstractListener就不需要扩展非抽象类,至少有一个方法接受一个类扩展AbstractEvent.那可能吗?
gus*_*afc 16
你已经得到了你想要的机制的名称 - 泛型!
首先,制作你的活动课程:
abstract class AbstractEvent {
// Insert fields/methods common for all events here
}
Run Code Online (Sandbox Code Playgroud)
没什么好奇的.接下来,创建一个参数化的侦听器类/接口,并为其类型参数赋予事件对象类的上限:
interface Listener<T extends AbstractEvent> {
void process(T event);
}
Run Code Online (Sandbox Code Playgroud)
您现在可以继续制作特定的活动课程:
class PonyEvent extends AbstractEvent {
// Pony-specific stuff goes here
}
Run Code Online (Sandbox Code Playgroud)
而且,这应该是你所需要的.继续并实现您的侦听器类:
class LoggingPonyListener implements Listener<PonyEvent> {
@Override
public void process(PonyEvent event){
System.out.println("Pony event occurred: " + event);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可能想要编写一个通用的事件调度类,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
看起来很甜蜜,嗯?你可以做这样的事情:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new LoggingPonyListener());
dispatcher.dispatchEvent(new PonyEvent());
Run Code Online (Sandbox Code Playgroud)
完全甜蜜,我们可以使用这些东西,然后当我们使用它时,继续重复使用它.但是有一个问题.假设你有一个聪明的开发人员想要一个超级简单的监听器,它实际上并没有对事件对象做任何事情,只是在事件发生时打印一个指定的消息.
不是真的考虑你真棒的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);
}
}
Run Code Online (Sandbox Code Playgroud)
这应该是可重用的,对吧?不,这不起作用:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new DebugListener("pony event"));
Run Code Online (Sandbox Code Playgroud)
因为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);
}
}
Run Code Online (Sandbox Code Playgroud)
这给你你后的行为:就像你可以发送PonyEvent到process的方法Listener<AbstractEvent>(因为PonyEvent是-的AbstractEvent),你现在可以使用事件调度类参数,类型为火听众参数与其父类型之一.
| 归档时间: |
|
| 查看次数: |
967 次 |
| 最近记录: |