我有一個抽象類AbstractEvent
和一些擴展它的「真實」類。我想用一個方法process(??? event)
創建一個抽象類AbstractListener
,以便擴展AbstractListener
的非抽象類將被要求至少有一個方法接受延伸爲AbstractEvent
的類。那可能嗎?Java中的泛型繼承
3
A
回答
16
你已經有了你想要的機制的名字 - generics!
首先,讓你的事件類:
abstract class AbstractEvent {
// Insert fields/methods common for all events here
}
沒什麼奇怪有關。接下來,創建一個參數化的監聽器類/接口,並給予其類型參數的上限,以您的活動對象類:
interface Listener<T extends AbstractEvent> {
void process(T event);
}
您現在可以讓您的具體事件類:
class PonyEvent extends AbstractEvent {
// Pony-specific stuff goes here
}
而且,那麼,這應該幾乎是你所需要的。去和實現監聽器類:
class LoggingPonyListener implements Listener<PonyEvent> {
@Override
public void process(PonyEvent event){
System.out.println("Pony event occurred: " + event);
}
}
現在,你可能會寫一個通用的事件分派類是這樣的:
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<T>> listeners =
new CopyOnWriteArrayList<Listener<T>>();
public void addListener(Listener<T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<T> listener : listeners)
listener.process(event);
}
}
看起來很不錯,不是嗎?你可以做這樣的東西:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new LoggingPonyListener());
dispatcher.dispatchEvent(new PonyEvent());
完全甜的,我們可以只使用這東西,然後當我們已經用它,只是不斷的重複使用它。但有一個問題。假設你有一個聰明的開發人員想要一個超級簡單的偵聽器,它並不事實上對事件對象做任何事情,但只要事件發生就打印指定的消息。
沒有真正考慮你真棒EventDispatcher
實用類,它是這樣寫的:
class DebugListener implements Listener<AbstractEvent> {
private final String msg;
public DebugListener(String msg) { this.msg = msg; }
@Override
public void process(AbstractEvent event){
System.out.println(msg);
}
}
這應該是可重複使用的,對不對?否。這是行不通的:
EventDispatcher<PonyEvent> dispatcher = new EventDispatcher<PonyEvent>();
dispatcher.add(new DebugListener("pony event"));
因爲DebugListener
是Listener<AbstractEvent>
,而不是一個Listener<PonyEvent>
。解決這個問題的方法是使用一個下界參數類型:
class EventDispatcher<T extends AbstractEvent> {
private final List<Listener<? super T>> listeners =
new CopyOnWriteArrayList<Listener<? super T>>();
public void addListener(Listener<? super T> listener) {
listeners.add(listener);
}
public void dispatchEvent(T event) {
for (Listener<? super T> listener : listeners)
listener.process(event);
}
}
這給你你後的行爲:就像你可以發送PonyEvent
到Listener<AbstractEvent>
的process
方法(因爲一個PonyEvent
is-an AbstractEvent
),你現在可以使用帶有一個類型參數的事件分派器類來觸發用它的一個超類型參數化的監聽器。
0
public abstract class AbstractListener {
public abstract void process(AbstractEvent event...);
}
試試看。這會創建一個名爲AbstractListener的抽象類,該抽象類具有一個抽象方法,該方法需要一個或多個抽象事件。如果你絕對必須始終有一個事件,你可以嘗試這樣的事情(雖然我不記得,如果這在技術上是可能的):
public abstract class AbstractListener {
public abstract void process(AbstractEvent event1, AbstractEvent otherEvents...);
}
希望有所幫助。
相關問題
- 1. Java泛型繼承
- 2. 的Java:泛型繼承
- 3. JAVA:泛型類繼承和泛型類型繼承
- 4. Java泛型繼承警告
- 5. Java繼承和泛型
- 6. java繼承vs泛型
- 7. Java泛型在繼承中的Android
- 8. 泛型或繼承/ Java中的接口?
- 9. 繼承,泛型和Java中的鑄造
- 10. 泛型中的繼承
- 11. 泛型方法和繼承Java中
- 12. 泛型類型的繼承
- 13. 繼承和泛型
- 14. 繼承和泛型
- 15. 泛型和繼承
- 16. 繼承泛型類
- 17. Kotlin泛型繼承
- 18. 繼承與泛型
- 19. 從Java繼承泛型的問題
- 20. 關於繼承的泛型混淆 - Java
- 21. Java泛型:無繼承的邊界
- 22. Java - 從接受泛型的類繼承?
- 23. Java泛型繼承神祕的錯誤
- 24. 泛型類型和繼承
- 25. 繼承和泛型類型
- 26. C#泛型類型繼承
- 27. Java-聽衆,泛型和繼承
- 28. Java泛型集合和繼承
- 29. Java泛型比得上繼承
- 30. Java泛型和繼承問題