用Java进行多态调度

use*_*638 13 java double-dispatch

在下文中,我希望EventHandler以一种方式处理EventA,以另一种方式处理EventB,以及以另一种方式处理任何其他事件(EventC,EventD).EventReceiver仅接收对Event的引用并调用EventHandler.handle().当然,总是被调用的版本是EventHandler.handle(事件事件).

不使用instanceOf,有没有办法多态调度(可能通过EventHandler或泛型中的另一个方法)到适当的句柄方法?

class EventA extends Event {
}

class EventB extends Event {
}

class EventC extends Event {
}

class EventD extends Event {
}

class EventHandler {
    void handle(EventA event) {
       System.out.println("Handling EventA");
    }

    void handle(EventB event) {
       System.out.println("Handling EventB");
    }

    void handle(Event event) {
       System.out.println("Handling Event");
    }
}

class EventReceiver {
    private EventHandler handler;

    void receive(Event event) {
        handler.handle(event);
    }
}    
Run Code Online (Sandbox Code Playgroud)

Pét*_*rök 14

听起来像应用(访问者模式的变体)的情况.(在主流的OO语言中,如C++,C#和Java,方法是单一调度,即一次只能在一种类型上进行多态.访问者允许实现双重调度.)

然而,这要求您也能够修改Event类,并创建从Events到(基本接口)的依赖关系EventHandler.

class EventA extends Event {
  public handleBy(EventHandler eh) {
    eh.handleEventA(this);
  }
}

class EventB extends Event {
  public handleBy(EventHandler eh) {
    eh.handleEventB(this);
  }
}

class EventHandler {
    void handleEventA(EventA event) {
       System.out.println("Handling EventA");
    }

    void handleEventB(EventB event) {
       System.out.println("Handling EventB");
    }

    void handle(Event event) {
       event.handleBy(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我想因为 Java 只支持单次调度,所以多次调度只能被 kluged/mocked,就像这里和访问者维基百科文章中所做的那样。另外,我认为双重调度包括 1)基于参数的调度(通过 Java 中的函数重载),以及 2)调用方法的对象上的标准多态性......但在这种情况下,`eh` 不是多态的,所以实际上我们这里只有 1) 类型的调度。 (2认同)