在 Java 中,由於不支援像 C/C++ 那樣的函式指標,我們無法直接將方法傳遞給事件源。但透過介面,我們可以輕鬆實作類似的回調機制。核心概念在於定義一個簡單的介面,宣告一個期望被回調的方法。
首先定義一個介面,代表感興趣的事件:
public interface InterestingEvent {
// 這是一個普通方法,可接受參數、也可返回值
void interestingEvent();
}
事件通知者持有這個介面的引用,當事件發生時呼叫該方法:
class EventNotifier {
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier(InterestingEvent event) {
ie = event;
somethingHappened = false;
}
public void doWork() {
if (somethingHappened) {
// 事件發生時,透過呼叫介面方法來通知
ie.interestingEvent();
}
}
}
想要接收事件通知的類別必須實作 InterestingEvent 介面,並將自身引用傳遞給通知者:
public class CallMe implements InterestingEvent {
private EventNotifier en;
public CallMe() {
// 新建一個事件通知者物件,並把自己傳遞給它
en = new EventNotifier(this);
}
// 實作事件發生時,實際處理事件的方法
@Override
public void interestingEvent() {
// 這個事件發生了,進行處理
}
}
實際應用中,通常需要註冊多個對同一事件感興趣的物件。以下展示如何擴充以支援多重監聽器:
interface InterestingEvent {
void interestingEvent(String event);
}
class CallMe implements InterestingEvent {
private String name;
public CallMe(String name) {
this.name = name;
}
@Override
public void interestingEvent(String event) {
System.out.println(name + ":[" + event + "] happened");
}
}
class EventNotifier {
private List<CallMe> callMes = new ArrayList<>();
public void regist(CallMe callMe) {
callMes.add(callMe);
}
public void doWork() {
for (CallMe callMe : callMes) {
callMe.interestingEvent("sample event");
}
}
}
public class CallMeTest {
public static void main(String[] args) {
EventNotifier ren = new EventNotifier();
CallMe a = new CallMe("CallMe A");
CallMe b = new CallMe("CallMe B");
// 註冊監聽器
ren.regist(a);
ren.regist(b);
// 觸發事件
ren.doWork();
}
}
透過這個簡單範例,我們展示了 Java 中利用介面實作回調機制的核心模式,並延伸到支援多重監聽器的實際應用場景。