2012-12-16 54 views
1

假設我有:的Java協方差/禁忌方差

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(五)無法編譯,因爲爲handleEvent(事件)是不確定的。有沒有解決方案?或者我必須問問它是什麼樣的事件?

+0

看來,您正在嘗試重新創建代數數據類型和模式匹配。你的「void HandleEvent」只是靜態重載,它是由靜態類型信息調度的,所以它們不適合。對於所需的行爲,您應該問「事件」類型的事件,或者使用訪問者等重磅調度模式。還要考慮切換到Scala。 – aemxdp

+1

聽起來像訪問者模式的工作。我試圖回答一個[類似的問題](http://stackoverflow.com/a/13150467/697630)最近也許它包含一些有趣的想法,可能不是答案,但值得考慮。 –

回答

4

通常的習慣用法是傳遞一個事件並讓多態處理它。

我在您的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上。