【问题标题】:java co-variance/contra-variancejava协变/逆变
【发布时间】:2012-12-03 20:00:27
【问题描述】:

假设我有:

class Event {}
class DoorBell extends Event {}
class PhoneCall extends Event {}
class EventGenerator {
    static Event getEvent() {
         if (today.isSunday())
            return new DoorBell()
         else 
            return new PhoneCall();
    }
}
class EventHandler {    
    void HandleEvent(DoorBell doorBell) { answer door; }
    void HandleEvent(PhoneCall phoneCall) { answer phone; }
    void consumeEvent() {
         Event e = EventGenerator.getEvent();
         HandleEvent(e);
    }
}

HandleEvent(e) 无法编译,因为 HandleEvent(Event) 未定义。有解决方案吗?还是我得问一下这是什么活动?

【问题讨论】:

  • 看来,您正在尝试重新发明代数数据类型和模式匹配。您的“void HandleEvent”只是静态重载,由静态类型信息调度,因此它们不适合。对于所需的行为,您应该使用“is”询问 Event 的类型,或者使用一些重量级的调度模式,如访问者。还可以考虑切换到 Scala。
  • 听起来像是访问者模式的工作。我最近尝试回答similar question,也许它包含一些有趣的想法,可能不是答案,但值得考虑。

标签: java inheritance covariance contravariance


【解决方案1】:

通常的习惯用法是传递一个事件,让多态性为您处理一切。

如果没有任何行为,我认为您的 EventHandler 类没有任何价值。你的设计,正如所提出的,没有提供多态性的好处。这就是你必须检查类型的原因。最好有这样的东西:

public interface EventHandler {
    void handle(Event event);
}

Visitor pattern(又名“双重调度”)可能是处理这种情况的好方法。

或者你可以试试泛型:

public class EventHandler {
   public <T> void consumeEvent(T event) {
       // handler code here, dependent on T
   }
}

我不知道 JDK 7 是否有新的东西可以帮助你。对不起;我仍然坚持使用 JDK 6。

【讨论】:

    猜你喜欢
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 2015-02-09
    • 2012-04-06
    • 1970-01-01
    • 2011-06-23
    相关资源
    最近更新 更多