原帖:http://www.blogjava.net/Carter0618/archive/2007/08/19/137936.html
1
.介面回調是什麼
[2]
?介面回調是指:可以把使用某一介面的類建立的對象的引用賦給該介面聲明的介面變數,那麼該介面變數就可以調用被類實現的介面的方法。實際上,當介面變數調用被類實現的介面中的方法時,就是通知相應的對象調用介面的方法,這一過程稱為對象功能的介面回調。看下面樣本。
interface People{ void peopleList();}class Student implements People{ public void peopleList(){ System.out.println("I’m a student.");}}class Teacher implements People{ public void peopleList(){ System.out.println("I’m a teacher.");}}public class Example{ public static void main(String args[]){ People a; //聲明介面變數a=new Student(); //執行個體化,介面變數中存放對象的引用a.peopleList(); //介面回調a=new Teacher(); //執行個體化,介面變數中存放對象的引用a.peopleList(); //介面回調}}結果:I’m a student.I’m a teacher.再來看看向上轉型(upcasting)的概念。
2
.什麼是向上轉型
[1]
?
Shape s=new Circle();這裡,建立了一個Circle對象,並把得到的引用立即賦值給Shape。通過繼承,Circle就是一種Shape。假設你調用基類方法(它已在匯出類中被覆蓋):s.draw();由於後期綁定(多態),將會正確調用Circle.draw()方法。
3
.向上轉型與介面回調的區別看似向上轉型和介面回調是一回事。看下面兩句話,均出自Thinking in Java。使用介面的核心原因:為了能夠向上轉型為多個基底類型[1]。即利用介面的多實現,可向上轉型為多個介面基底類型(具體見《抽象與介面》章節6)。從實現了某介面的對象,得到對此介面的引用,與向上轉型為這個對象的基類,實質上效果是一樣的。(此句摘自Thinking in Java 3rd 介面與內部類一章)所以,我認為,這兩個概念是從兩個方面來解釋一個行為。介面回調的概念,強調使用介面來實現回調對象方法使用權的功能(下一章節詳細分析)。而向上轉型則牽涉到多態和運行期綁定的範疇。
4
.用 Java
介面實現回呼函數的等價功能熟悉 MS-Windows 和 X Window System 事件驅動編程模型的開發人員,習慣於傳遞在某種事件發生時調用(即“回調”)的函數指標。Java 的物件導向模型目前並不支援方法指標,Java 的介面支援提供了一種獲得回調的等價功能的機制。其技巧就是:定義一個簡單介面,並在該介面中聲明我們要調用的方法。假定我們希望在某個事件發生時得到通知。我們可以定義一個介面:InterestingEvent.java
| package org.zj.sample;public interface InterestingEvent { public void interestingEvent ();} |
這使得我們可以控制實現該介面的類的任何對象。因此,我們不必關心任何外部類型資訊。發出事件訊號的類必須等待實現了 InterestingEvent 介面的對象,並在適當時候調用 interestingEvent() 方法。EventNotifier.java
| package org.zj.sample;public class EventNotifier { private InterestingEvent ie; private boolean somethingHappened; public EventNotifier(InterestingEvent event) { ie = event; // 儲存事件對象以備後用。 somethingHappened = false; // 還沒有要報告的事件。 } public void doWork() { if (somethingHappened) { // 檢查設定的謂詞。 ie.interestingEvent();// 通過調用介面的這個方法發出事件訊號。 } } public void setHappened(){//設定謂詞。 somethingHappened=true; }} |
在上例中,使用 somethingHappened 謂詞來跟蹤是否應觸發事件。希望接收事件通知的代碼必須實現 InterestingEvent 介面,並將自身引用傳遞給事件通知程式。CallMe.java
| package org.zj.sample;public class CallMe implements InterestingEvent { @SuppressWarnings("unused") private EventNotifier en; public CallMe() { // 注意 EventNotifier (InterestingEvent event),應該傳遞一個介面類型。 // 而下面將this,即實現了InterestingEvent介面的CallMe執行個體傳遞給//EventNotifier。也就是所謂的介面回調了。 en = new EventNotifier(this); // 建立事件通知程式,並將自身引用傳遞給它。 } // 為事件定義實際的處理常式。 public void interestingEvent() { System.out.println("Call me Hello."); }} |
下面寫個測試類別。Test.java
| package org.zj.sample;public class Test { public static void main(String[] args) { EventNotifier en=new EventNotifier(new CallMe()); en.setHappened(); en.doWork(); }} |
結果:Call me Hello.
5
.參考資料[1]Thinking in Java 3rd[2]耿祥義,Java實用教程,清華大學出版社[3] John D. Mitchell,Java 介面實現回呼函數的等價功能,IBMDeveloper網站