2012-04-05 91 views
3

我有一個接口(稱爲Subject),其具有以下的方法:重寫的方法與多態參數

public void addObserver(Observer o); 

我然後具有延伸Subject稱爲TimerSubject另一個接口。該接口是用於計時的更具體的Subject版本。它還有其他一些其他的方法。

還有兩個對應的接口,ObserverTimerObserverTimerObserver延伸Observer

當一個類實現TimerSubject時,它必須覆蓋方法從Subject接口。這看起來是這樣的:

@Override 
public void addObserver(**Observer e**) { 
    observers.add(e); 
} 

的問題是,我需要的方法來接受的TimerObserver代替Observer,whitch應該是這樣的:

@Override 
public void addObserver(**TimerObserver e**) { 
    observers.add(e); 
} 

這是不行的,因爲參數是與被覆蓋的方法的參數不一樣。

那麼有沒有一種方法來覆蓋多態的參數的方法?

+0

您可以使用泛型 – 2012-04-05 05:54:26

回答

1

幾個解決方案浮現在腦海中:

你TimerSubject實現可以通過,如果它收到一個說法,是不是TimerObserver拋出一個RuntimeException實現公共無效的addObserver(觀察員)。你失去了對編譯器強制類型的保護,但後期綁定對於「真正」多態是相當典型的。

或者,您的TimerSubject接口可以簡單地爲新行爲指定一個新方法addTimerObserver。推測你的TimerSubject擴展了一個已經實現了addObserver(Observer)的Subject;如果該實現完全不可用,則可以覆蓋並拋出錯誤。但是,如果TimerSubject實際上沒有用於addObserver(Observer)方法,並且該方法完全不可用,那麼這兩個對象可能不像您所期望的那樣具有多態性。 :)

2

我不得不這樣做一次,我落得這樣做templatizing它,即

interface Subject<T extends Observer> { 
public void addObserver(T e); 
} 

class TimerSubject implements Subject<TimerObserver> { 
// ... 
@Override 
public void addObserver(TimerObserver e) 
{ 
    observers.add(e); 
} 
} 

這使的addObserver方法多態性和靜態強制執行的參數類型。

這裏的想法是,如果你想要主題接口的每個具體實現者添加不同種類的觀察者。所以你讓Subject接口要求它。通過使泛​​型類T擴展Observer,您仍然可以保證使用addObserver方法的用戶僅用於添加觀察者,這是一項獎勵。這樣你也可以編寫一個多態的getter,就像

public T getObserver(T e); 

填寫任何派生類的類型。這樣

Subject<?> foo = new TimerSubject(); 
// add observer somewhere 
Observer bar = foo.getObserver(); 

也會靜態類型檢查。(注意:我在這裏工作,所以最後一點可能不完全正確,但肯定有某種方式可以得到它。)