代码之家  ›  专栏  ›  技术社区  ›  Fluffy

Java中的泛型继承

  •  3
  • Fluffy  · 技术社区  · 14 年前

    我有一门抽象课 AbstractEvent 还有一些“真实”的类来扩展它。我想做一个抽象类 AbstractListener 用一种方法 process(??? event) 使非抽象类 抽象侦听器 抽象事件

    2 回复  |  直到 14 年前
        1
  •  16
  •   gustafc    14 年前

    你已经知道你想要的机械装置的名字了- 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 ),现在可以使用使用类型参数化的事件调度程序类来激发使用其超类型之一参数化的侦听器。

        2
  •  0
  •   aperkins    14 年前
    public abstract class AbstractListener {
        public abstract void process(AbstractEvent event...);
    }
    

    试试看。它创建了一个名为AbstractListener的抽象类,该类有一个接受一个或多个抽象事件的抽象方法。如果你绝对必须总是有一个事件,你可以尝试这样的事情(虽然我不记得这在技术上是否可行):

    public abstract class AbstractListener {
        public abstract void process(AbstractEvent event1, AbstractEvent otherEvents...);
    }
    

    希望有帮助。