我有一个抽象类AbstractEvent
和一些扩展它的“真实”类。我想用一个方法process(??? event)
创建一个抽象类AbstractListener
,以便扩展AbstractListener
的非抽象类将被要求至少有一个方法接受延伸为AbstractEvent
的类。那可能吗?Java中的泛型继承
3
A
回答
16
你已经有了你想要的机制的名字 - 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
到Listener<AbstractEvent>
的process
方法(因为一个PonyEvent
is-an AbstractEvent
),你现在可以使用带有一个类型参数的事件分派器类来触发用它的一个超类型参数化的监听器。
0
public abstract class AbstractListener {
public abstract void process(AbstractEvent event...);
}
试试看。这会创建一个名为AbstractListener的抽象类,该抽象类具有一个抽象方法,该方法需要一个或多个抽象事件。如果你绝对必须始终有一个事件,你可以尝试这样的事情(虽然我不记得,如果这在技术上是可能的):
public abstract class AbstractListener {
public abstract void process(AbstractEvent event1, AbstractEvent otherEvents...);
}
希望有所帮助。
相关问题
- 1. Java泛型继承
- 2. JAVA:泛型类继承和泛型类型继承
- 3. Java泛型在继承中的Android
- 4. 继承,泛型和Java中的铸造
- 5. 泛型中的继承
- 6. 泛型方法和继承Java中
- 7. 泛型类型的继承
- 8. Kotlin泛型继承
- 9. 继承与泛型
- 10. 继承和泛型
- 11. 泛型和继承
- 12. 关于继承的泛型混淆 - Java
- 13. 从Java继承泛型的问题
- 14. 继承和泛型类型
- 15. Java泛型和继承问题
- 16. Java泛型比得上继承
- 17. Java-听众,泛型和继承
- 18. Java泛型集合和继承
- 19. protobuf的,继承和泛型
- 20. 多泛型类继承
- 21. C#泛型/动态继承
- 22. C#多重泛型继承
- 23. 继承和泛型C#
- 24. C++泛型类和继承
- 25. 继承泛型类C#
- 26. 类在Swift中继承它的泛型
- 27. Java泛型,为什么在泛型中使用继承是非法的?
- 28. 继承与C#泛型,而类继承类型
- 29. C#泛型,其中T类:(继承类)
- 30. Java泛型,不兼容类型的错误(与继承)