2010-12-09 61 views
3

好的。所以我正在嘗試使用觀察者模式爲應用程序設置一個GUI。以標準方式;如果一個可觀測的更新它所謂的所有觀察員的更新方法,傳遞一個ComponentUpdateEvent,如下:Java:方法簽名中類型的子類

public interface Observable { 
ArrayList<Observer> observers = new ArrayList<Observer>(); 

public void updateObservers(); 

public void addObserver(Observer observer); 

public void removeObserver(Observer observer); 
} 

public interface Observer { 
public void update(ComponentUpdateEvent updateEvent); 
} 

public abstract class ComponentUpdateEvent { 
public abstract ComponentType getComponentType(); 
} 

我有一些不同的組件,其實現可觀的,在應用程序中的「模型」的一面。每種類型的組件都有一個Drawer類的獨立子類,它實現了Observer,用於渲染JPanel。

問題是,我試圖使它在調用Drawer子類的更新方法時,傳遞的updateEvent參數可以是ComponentUpdateEvent的子類。

但是,很明顯,如果我嘗試和做法如下:

@Override 
public void update(ConsoleUpdateEvent updateEvent) throws Exception { 
    if (this.componentType != updateEvent.get)) { 
    throw new Exception("ComponentType Mismatch."); 
    } 
    else { 
    messages = updateEvent.getComponentState(); 
    } 
} 

我得到的編譯器錯誤:

The method update(ConsoleUpdateEvent) of type ConsoleDrawer must override or implement a supertype method. 

因爲該方法的簽名是不一樣的。我似乎無法解決這個問題,而沒有爲每種類型的組件分別設置觀察者類,是否可以用泛型來解決這個問題?任何幫助,將不勝感激。

回答

-1

通常,Java允許您在覆蓋方法時弱化返回值,或者強化參數。但是,在這種情況下,您正試圖削弱參數。

也許泛型可以提供幫助。我不得不承認,我還沒有試過下面的代碼,這僅僅是從內存:

您可以嘗試在Observer接口的簽名使用泛型:

public interface Observer<T> 

public interface Observer<T extends ComponentUpdateEvent> 

除此之外,我會修改Observable接口的簽名。

public void addObserver(Observer<T extends ComponentUpdateEvent> observer) 
+1

要麼你的強化和弱化的定義與我的相反,要麼你倒退了第一個句子。重寫方法的返回類型可能更具體(我稱之爲「更強」),而參數可能不太具體(「更弱」)。它引發的類型與返回類型的行爲類似。 – 2010-12-09 18:20:13

2

你的接口必須聲明它爲throws Exception來解決你的編譯錯誤。原因是你不會傳遞類的類型,你通過Observer接口。所以,如果一個實現了Observable的類拋出異常,調用類將不會知道它,除非接口指定它。

0

在您的Observer界面中,您的update()方法不是throw Exception而您的ConsoleDrawer.update()確實如此。根據java,這兩個是不一樣的。

您可以在ConsoleDrawer上刪除throw Exception或在Observer接口上添加例外。