隨筆-72  評論-20  文章-0  trackbacks-1
          1.接口回調是什么[2]
          接口回調是指:可以把使用某一接口的類創(chuàng)建的對象的引用賦給該接口聲明的接口變量,那么該接口變量就可以調用被類實現(xiàn)的接口的方法。實際上,當接口變量調用被類實現(xiàn)的接口中的方法時,就是通知相應的對象調用接口的方法,這一過程稱為對象功能的接口回調。看下面示例。
          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();
          這里,創(chuàng)建了一個Circle對象,并把得到的引用立即賦值給Shape。通過繼承,Circle就是一種Shape。
          假設你調用基類方法(它已在導出類中被覆蓋):
          s.draw();
          由于后期綁定(多態(tài)),將會正確調用Circle.draw()方法。
           
          3.向上轉型與接口回調的區(qū)別
          看似向上轉型和接口回調是一回事。看下面兩句話,均出自Thinking in Java
          使用接口的核心原因:為了能夠向上轉型為多個基類型[1]。即利用接口的多實現(xiàn),可向上轉型為多個接口基類型(具體見《抽象與接口》章節(jié)6)。
          從實現(xiàn)了某接口的對象,得到對此接口的引用,與向上轉型為這個對象的基類,實質上效果是一樣的。(此句摘自Thinking in Java 3rd 接口與內(nèi)部類一章)
          所以,我認為,這兩個概念是從兩個方面來解釋一個行為。接口回調的概念,強調使用接口來實現(xiàn)回調對象方法使用權的功能(下一章節(jié)詳細分析)。而向上轉型則牽涉到多態(tài)和運行期綁定的范疇。
           
          4.用 Java 接口實現(xiàn)回調函數(shù)的等價功能
          熟悉 MS-Windows X Window System 事件驅動編程模型的開發(fā)人員,習慣于傳遞在某種事件發(fā)生時調用(即回調)的函數(shù)指針。Java 的面向對象模型目前并不支持方法指針,Java 的接口支持提供了一種獲得回調的等價功能的機制。其技巧就是:定義一個簡單接口,并在該接口中聲明我們要調用的方法。
          假定我們希望在某個事件發(fā)生時得到通知。我們可以定義一個接口:
          InterestingEvent.java
          package org.zj.sample;
          public interface InterestingEvent {
              public void interestingEvent ();
          }
          這使得我們可以控制實現(xiàn)該接口的類的任何對象。因此,我們不必關心任何外部類型信息。
          發(fā)出事件信號的類必須等待實現(xiàn)了 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();// 通過調用接口的這個方法發(fā)出事件信號。
                   }
              }
             
              public void setHappened(){//設置謂詞。
                   somethingHappened=true;
              }
          }
          在上例中,使用 somethingHappened 謂詞來跟蹤是否應觸發(fā)事件。希望接收事件通知的代碼必須實現(xiàn) InterestingEvent 接口,并將自身引用傳遞給事件通知程序。
          CallMe.java
          package org.zj.sample;
          public class CallMe implements InterestingEvent {
              @SuppressWarnings("unused")
              private EventNotifier en;
           
              public CallMe() {
                   // 注意 EventNotifier (InterestingEvent event),應該傳遞一個接口類型。
                   // 而下面將this,即實現(xiàn)了InterestingEvent接口的CallMe實例傳遞給
          //EventNotifier。也就是所謂的接口回調了。
                   en = new EventNotifier(this); // 創(chuàng)建事件通知程序,并將自身引用傳遞給它。
              }
           
              // 為事件定義實際的處理程序。
              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. MitchellJava 接口實現(xiàn)回調函數(shù)的等價功能,IBMDeveloper網(wǎng)站

          posted on 2007-08-19 14:05 前方的路 閱讀(10306) 評論(4)  編輯  收藏 所屬分類: Java技術

          評論:
          # re: 什么是接口回調? 2008-08-07 01:41 | freedoom
          寫得真的很好,吸收了,多謝LZ。  回復  更多評論
            
          # re: 什么是接口回調? 2011-03-12 16:37 | zhanliqing
          例子有點像觀察者模式  回復  更多評論
            
          # re: 什么是接口回調?[未登錄] 2011-05-05 08:49 |
          怎么感覺類CallMe中的構造方法沒有任何意義 因為根本無法向外部傳遞信息任何人消息  回復  更多評論
            
          # re: 什么是接口回調? 2011-05-06 01:19 | kenma143
          這個問題我也想了好久 想不明白這個構造函數(shù)的意思和運行方式
          最后身體力行 編譯運行了一遍 然后把CallMe的構造函數(shù)內(nèi)容刪了 然后再編譯運行了一遍 發(fā)現(xiàn)沒有問題
          所以我覺得 這里作者錯了 這里的確運用了 接口調用 但不是這一句
          en = new EventNotifier(this);
          而是這一句
          EventNotifier en=new EventNotifier(new CallMe());
          如果有錯,請指出。  回復  更多評論
            
          主站蜘蛛池模板: 城口县| 乐业县| 绥棱县| 开鲁县| 旬阳县| 洞口县| 丽江市| 云林县| 抚松县| 建平县| 焉耆| 定结县| 门头沟区| 宁晋县| 惠水县| 明光市| 鹤岗市| 施秉县| 瓦房店市| 伊宁市| 兴城市| 浦县| 威宁| 博野县| 梁山县| 湟中县| 肇东市| 长汀县| 都江堰市| 甘德县| 固安县| 嵊州市| 淮阳县| 明光市| 遂川县| 新民市| 石嘴山市| 凤冈县| 灵璧县| 满洲里市| 娱乐|