Java的接口支持提供瞭一種獲得回調的等價功能的機制。其技巧是:定義一個簡單的接口,並在該接口中聲明我們要調用的方法。其特點是:一個實例持有一個接口的引用
例如,假設我們希望在某個時間發生時得到通知。我們可以定義一個接口:
Java代碼
package com.wxy.callback;
public interface InterestingEvent {
/**
*這是一個常規方法,如果需要,可以有返回值,也可以接受參數
*/
public void interestingEvent();
}
這使得我們可以控制實現該接口的類得任何對象。因此,我們不必關心任何外部類型信息。發出事件信號的類必須等待實現瞭InterestingEvent接口的對象,並在適當時候調用interestingEvent()方法。
Java代碼
package com.wxy.callback;
public class EventNotifier {
/**事件對象*/
private InterestingEvent ie;
/**事件發生狀態*/
private boolean somethingHappend;
/**
* 構造函數,傳入事件對象以備後用
* @param event 事件對象
*/
public EventNotifier(InterestingEvent event) {
this.ie = event;
//事件未發生狀態
somethingHappend = false;
}
/**
* 事件發生,調用InterestingEvent事件發生對象的方法發出事件信號
*/
public void doWork() {
//檢查在別處設置的謂詞
if (somethingHappend) {
//通過調用接口的這個方法發出事件信號
ie.interestingEvent();
}
}
}
在EventNotifier中,使用somethingHappend謂詞來跟蹤是否哦應觸發事件。在許多情況下,調用此方法足以保證向interesthingEvent()發出信號。
希望接受事件通知的代碼必須實現Interestingevent接口,並將自身引用傳遞給事件通知程序。
Java代碼
public class CallMe implements InterestingEvent {
private EventNotifier en;
/**
* 創建事件通知程序,並將自身引用傳遞給它
*/
public CallMe() {
this.en = new EventNotifier(this);
}
/**
* 為事件定義實際的處理程序
*/
@Override
public void interestingEvent() {
System.out.println("oh,something interesting has happended!");
System.out.println("do some action!");
}
public EventNotifier getEn() {
return en;
}
public void setEn(EventNotifier en) {
this.en = en;
}
}
下面是一個典型的回調案例:公司員工工作,工作完成後主管要求員工匯報工作完成情況。
事件接口:
Java代碼
package com.wxy.callback;
public interface Event {
/**
* 返回發生事件信息
* @return 事件信息
*/
public String happendEvent();
}
事件具體實現類:
Java代碼
package com.wxy.callback;
public class EventA implements Event {
@Override
public String happendEvent() {
return "job has been finished!";
}
}
Java代碼
package com.wxy.callback;
public class EventB implements Event {
@Override
public String happendEvent() {
return "job has been finished!";
}
}
主管類:
Java代碼
package com.wxy.callback;
public class Boss {
private String name;
public Boss(String name) {
this.name = name;
}
public void getStaffEvent(Staff staff, Event event) {
System.out.println("the msg what the boss received is–" + staff.getName() + ":"
+ event.happendEvent());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
員工類:
Java代碼
package com.wxy.callback;
public class Staff {
private Event event; //事件
private String name; //員工姓名
private Boss boss; //員工所屬主管
/**
* 員工構造器
* @param name 員工姓名
* @param boss 傳入Boss對象,便於回調反饋工作狀況
*/
public Staff(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
public void doWork() {
System.out.println(name + " is doing working…");
//do somtething…..
for (int i = 0; i < 10; i++) {
System.out.println("sheep" + i);
}
System.out.println(name + " was finished work!");
//tell the boss what has happend,這裡就是boss的回調方法
boss.getStaffEvent(this, event);
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boss getBoss() {
return boss;
}
public void setBoss(Boss boss) {
this.boss = boss;
}
}
測試類:
Java代碼
package com.wxy.callback;
public class StaffBossTest {
public static void main(String args[]) {
//初始化員工和主管
Boss boss = new Boss("boss");
Staff staffA = new Staff("staffA", boss);
Staff staffB = new Staff("staffB", boss);
//主管發放瞭兩個新任務
Event event1 = new EventA();
Event event2 = new EventB();
//員工接受任務開始幹活
staffA.setEvent(event1);
staffB.setEvent(event2);
//員工幹晚活,及時向主管反饋工作情況
staffA.doWork();
staffB.doWork();
}
}
測試結果:
Java代碼
staffA was finished work!
the msg what the boss received is–staffA:job has been finished!
staffB is doing working…
sheep0
sheep1
sheep2
sheep3
sheep4
sheep5
sheep6
sheep7
sheep8
sheep9
staffB was finished work!
the msg what the boss received is–staffB:job has been finished!
可以看到,當員工完成工作時(即觸發某事件時),staff對象調用boss對象的方法,實現回調功能。設計模式中,觀察者模式也是一個典型的應用回調機制的例子。