2010-09-13 85 views
3

我有一个抽象类AbstractEvent和一些扩展它的“真实”类。我想用一个方法process(??? event)创建一个抽象类AbstractListener,以便扩展AbstractListener的非抽象类将被要求至少有一个方法接受延伸为AbstractEvent的类。那可能吗?Java中的泛型继承

回答

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")); 

因为DebugListenerListener<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); 
    } 

} 

这给你你后的行为:就像你可以发送PonyEventListener<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...); 
} 

希望有所帮助。