編輯:關於Android編程
看見網上一些回調的解釋都很復雜的,特別基於Android的自定義回調,感覺一頭霧水,於是乎,我也寫了這篇基於我對回調的解釋。
先來看一個簡單的例子:
有兩個類 ClassA ,和 ClassB, ClassA調用ClassB裡面的方法,
public class ClassB { public void method_from_classB(){ for(int i=0;i<10;i++) System.out.print("..."+i); } } public class ClassA { public static void main(String args[]){ ClassB classB = new ClassB(); classB.method_from_classB(); } }
輸出:
...0...1...2...3...4...5...6...7...8...9
臥槽,哪個傻逼寫的博文,侮辱我的智商不是嗎,嘻嘻,是為了做比較,接下來看看利用回調, ClassA 是怎麼調用 ClassB中的 方法的,注意是回調:
讓ClassB 實現 ClassA定義的接口
public class ClassB implements ClassA.ClassAInterface{ public ClassB(){ new ClassA().RegisterInterface(this); System.out.println("...ClassB..."+this); } @Override public void method_from_interface() { for(int i=0;i<10;i++) System.out.print("..."+i); } /* public void method_from_classB(){ for(int i=0;i<10;i++) System.out.print("..."+i); }*/ }
ClassA裡面定義接口和抽象方法:
public class ClassA { public static ClassAInterface classAInterface; public interface ClassAInterface{ public void method_from_interface(); } public void RegisterInterface(ClassAInterface a_interface){ this.classAInterface = a_interface; System.out.println("...a_interface..."+a_interface); } public static void main(String args[]){ ClassB classB = new ClassB();// 標記@1,最後面做解釋 //classB.method_from_classB(); System.out.println("...classAInterface..."+classAInterface); if(classAInterface != null){ classAInterface.method_from_interface(); } } }
輸出:
...0...1...2...3...4...5...6...7...8...9
整理下,也就是 我在ClassA裡面定義了一個接口(interface),接口裡面又定義了一個方法,但沒有方法體,也就不做任何事情。
當 ClassA 執行到 mian() 函數時,就會調用接口的方法,但前面講了,接口的方法沒有實現具體的事情,它就會找到 ClassB 裡面對應的 方法,來實現具體的事情。
呦呦呦,ClassA 的接口的方法是怎麼找到 ClassB 的方法,難道會上天???
也就是下面分析這句代碼是怎麼上天的:
// 利用接口的回調實現 ClassB中 的方法的 具體事情
classAInterface.method_from_interface();
我在上面的代碼中用 System.out.println 打印出了日志做分析:
第一個(ClassA中的方法):
public void RegisterInterface(ClassAInterface a_interface){ this.classAInterface = a_interface; System.out.println("...a_interface..."+a_interface); }
輸出:
...a_interface...ClassB@3ddb8962
第二個:
public ClassB(){ new ClassA().RegisterInterface(this); System.out.println("...ClassB..."+this); }
輸出:
...ClassB...ClassB@3ddb8962
第三個:
System.out.println("...classAInterface..."+classAInterface); if(classAInterface != null){ classAInterface.method_from_interface(); }
輸出:
...classAInterface...ClassB@3ddb8962
看到這裡是不是恍然大悟呢 ,輸出都是 “ ClassB@3ddb8962 ” 也就是ClassB 對象的引用!!!
啊!接口只不過是將 ClassB 對象的引用 傳到 ClassA中而已,那這句會上天的語句是不是很好解釋了呢。
classAInterface.method_from_interface();
相當於 [email protected]_from_interface();
這是不是跟最上面到的代碼:
ClassB classB = new ClassB(); classB.method_from_classB();
一樣呢,這也是為什麼我最開始要舉這個例子的原因!!!
相信看到這裡應該理解了接口的回調是怎麼回事了吧。
但有一點又糊塗了,為什麼 要接口回調這麼麻煩的,最上面的在ClassA裡面執行:
ClassB classB = new ClassB(); classB.method_from_classB();
不是照樣可以 ClassA 調用 ClassB 裡面的 方法。。。。但要是ClassA 要調用ClassC,ClassD ...,裡面的方法呢,是不是還要改變ClassA裡面的代碼,實例化ClassC,ClassD ... 的對象,顯然是不好的,要是使用接口那就不用改變ClassA 裡面的代碼了,任何類只要實現ClassA 裡面的接口就可以.
解釋一下 標記@1 :
上面那段話好像跟 標記@1 違背了,在 ClassA 裡面確實也需要實例化 ClassB對象。
因為要 【利用】 初始化的時候執行構造方法裡面的代碼:
public ClassB(){ // 相當於回調事件的注冊,初學者出現回調空指針很有可能這邊忘記‘注冊'了 new ClassA().RegisterInterface(this); }
將this 傳遞給 ClassA ,作用也就是 上面利用 日志分析的作用。
但再 Android 開發中救你不必這樣了,
可以在 Activity 的初始化時執行:
@Override protected void onCreate(Bundle savedInstanceState) { // 相當於回調事件的注冊,初學者出現回調空指針很有可能這邊忘記‘注冊'了 new ClassA().RegisterInterface(this); }
在Android 開發中 ClassA 裡面的 mian() 函數可以用事件來代替,觸發:
如:
button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO 自動生成的方法存根 if(classAInterface != null){ classAInterface.method_from_interface(); } });
1.目標 androidannotation框架要促進Android應用程序的編寫和維護。相信簡單的代碼有明確的意圖是實現這些目
要研究的幾個問題 一、Behavior是什麼?為什麼要用Behavior? 二、怎麼使用Behavior? 三、從源碼角度看為什麼要這麼使用Behavior?一、Beha
上次我們學習如何從網絡上獲取一張圖片,今天我們學習如何從網絡上獲取文本文件,以XML文件為例子。因為XML文件在實際開發中最為常見。我們以下面圖片為例子學習如何從網絡上獲
相對與屬性動畫視圖動畫使用環境:view animation system提供的能力只能夠為View添加動畫。因此如果你想為非View對象添加動畫,就必須自己去實現,vi