JAVA 回調機制(callback)

序言java

最近學習java,接觸到了回調機制(CallBack)。初識時感受比較混亂,並且在網上搜索到的相關的講解,要麼一言帶過,要麼說的比較單純的像是給CallBack作了一個定義。固然了,我在理解了回調以後,再去看網上的各類講解,確實沒什麼問題。可是,對於初學的我來講,缺了一個按部就班的過程。此處,將我對回調機制的我的理解,按照由淺到深的順序描述一下,若有不妥之處,望不吝賜教!ide

開始以前,先想象一個場景:幼稚園的小朋友剛剛學習了10之內的加法。函數

第1章. 故事的緣起學習

幼師在黑板上寫一個式子 「1 + 1 = 」,由小明同窗來填空。測試

因爲已經學習了10之內的加法,小明同窗能夠徹底靠本身來計算這個題目,模擬該過程的代碼以下:this

複製代碼
 1 public class Student
 2 {
 3     private String name = null;
 4 
 5     public Student(String name)
 6     {
 7         // TODO Auto-generated constructor stub
 8         this.name = name;
 9     }
10     
11     public void setName(String name)
12     {
13         this.name = name;
14     }
15     
16     private int calcADD(int a, int b)
17     {
18         return a + b;
19     }
20     
21     public void fillBlank(int a, int b)
22     {
23         int result = calcADD(a, b);
24         System.out.println(name + "心算:" + a + " + " + b + " = " + result);
25     }
26 }
複製代碼

小明同窗在填空(fillBalnk)的時候,直接心算(clacADD)了一下,得出結果是2,並將結果寫在空格里。測試代碼以下:spa

複製代碼
 1 public class Test
 2 {
 3     public static void main(String[] args)
 4     {
 5         int a = 1;
 6         int b = 1;
 7         Student s = new Student("小明");
 8         s.fillBlank(a, b);
 9     }
10 }
複製代碼

 

運行結果以下:code

小明心算:1 + 1 = 2

該過程徹底由Student類的實例對象單獨完成,並未涉及回調機制。對象

第2章. 幼師的找茬blog

課間,幼師突發奇想在黑板上寫了「168 + 291 = 」讓小明完成,而後回辦公室了。

花擦!爲何全部老師都跟小明過不去啊?明明超綱了好很差!這時候小明同窗明顯不能再像上面那樣靠心算來完成了,正在懵逼的時候,班上的小紅同窗遞過來一個只能計算加法的計算器(奸商啊)!!!!而小明同窗剛好知道怎麼用計算器,因而經過計算器計算獲得結果並完成了填空。

計算器的代碼爲:

複製代碼
1 public class Calculator
2 {
3     public int add(int a, int b)
4     {
5         return a + b;
6     }
7 }
複製代碼

修改Student類,添加使用計算器的方法:

複製代碼
 1 public class Student
 2 {
 3     private String name = null;
 4 
 5     public Student(String name)
 6     {
 7         // TODO Auto-generated constructor stub
 8         this.name = name;
 9     }
10     
11     public void setName(String name)
12     {
13         this.name = name;
14     }
15     
16     @SuppressWarnings("unused")
17     private int calcADD(int a, int b)
18     {
19         return a + b;
20     }
21     
22     private int useCalculator(int a, int b)
23     {
24         return new Calculator().add(a, b);
25     }
26     
27     public void fillBlank(int a, int b)
28     {
29         int result = useCalculator(a, b);
30         System.out.println(name + "使用計算器:" + a + " + " + b + " = " + result);
31     }
32 }
複製代碼

測試代碼以下:

複製代碼
 1 public class Test
 2 {
 3     public static void main(String[] args)
 4     {
 5         int a = 168;
 6         int b = 291;
 7         Student s = new Student("小明");
 8         s.fillBlank(a, b);
 9     }
10 }
複製代碼

運行結果以下:

小明使用計算器:168 + 291 = 459

該過程當中仍未涉及到回調機制,可是部分小明的部分工做已經實現了轉移,由計算器來協助實現。

3. 幼師回來了

發現小明完成了3位數的加法,老師以爲小明很聰明,是個可塑之才。因而又在黑板上寫下了「26549 + 16487 = 」,讓小明上課以前完成填空,而後又回辦公室了。

小明看着教室外面撒歡兒的小夥伴,不由悲從中來。再不出去玩,這個課間就要廢了啊!!!! 看着小紅再一次遞上來的計算器,小明心生一計:讓小紅代勞。

小明告訴小紅題目是「26549 + 16487 = 」,而後指出填寫結果的具體位置,而後就出去快樂的玩耍了。

這裏,不把小紅單獨實現出來,而是把這個只能算加法的計算器和小紅當作一個總體,一個會算結果還會填空的超級計算器。這個超級計算器須要傳的參數是兩個加數和要填空的位置,而這些內容須要小明提早告知,也就是小明要把本身的一部分方法暴漏給小紅,最簡單的方法就是把本身的引用和兩個加數一塊告訴小紅。

所以,超級計算器的add方法應該包含兩個操做數和小明自身的引用,代碼以下:

複製代碼
1 public class SuperCalculator
2 {
3     public void add(int a, int b, Student  xiaoming)
4     {
5         int result = a + b;
6         xiaoming.fillBlank(a, b, result);
7     }
8 }
複製代碼

小明這邊如今已經不須要心算,也不須要使用計算器了,所以只須要有一個方法能夠向小紅尋求幫助就好了,代碼以下:

複製代碼
 1 public class Student
 2 {
 3     private String name = null;
 4 
 5     public Student(String name)
 6     {
 7         // TODO Auto-generated constructor stub
 8         this.name = name;
 9     }
10     
11     public void setName(String name)
12     {
13         this.name = name;
14     }
15     
16     public void callHelp (int a, int b)
17     {
18         new SuperCalculator().add(a, b, this);
19     }
20     
21     public void fillBlank(int a, int b, int result)
22     {
23         System.out.println(name + "求助小紅計算:" + a + " + " + b + " = " + result);
24     }
25 }
複製代碼

測試代碼以下:

複製代碼
 1 public class Test
 2 {
 3     public static void main(String[] args)
 4     {
 5         int a = 26549;
 6         int b = 16487;
 7         Student s = new Student("小明");
 8         s.callHelp(a, b);
 9     }
10 }
複製代碼

運行結果爲:

小明求助小紅計算:26549 + 16487 = 43036

執行流程爲:小明經過自身的callHelp方法調用了小紅(new SuperCalculator())的add方法,在調用的時候將自身的引用(this)當作參數一併傳入,小紅在使用計算器得出結果以後,回調了小明的fillBlank方法,將結果填在了黑板上的空格里。

燈燈燈!到這裏,回調功能就正式登場了,小明的fillBlank方法就是咱們常說的回調函數。

經過這種方式,能夠很明顯的看出,對於完成老師的填空題這個任務上,小明已經不須要等待到加法作完且結果填寫在黑板上才能去跟小夥伴們撒歡了,填空這個工做由超級計算器小紅來作了。回調的優點已經開始體現了。

第4章. 門口的婆婆

幼稚園的門口有一個頭發花白的老婆婆,天天風雨無阻在那裏擺着地攤賣一些快過時的垃圾食品。因爲年紀大了,腦子有些糊塗,常常算不清楚本身掙了多少錢。有一天,她無心間聽到了小明跟小夥伴們吹噓本身如何在小紅的幫助下與幼師鬥智鬥勇。因而,婆婆決定找到小紅牌超級計算器來作本身的小幫手,並提供一包衛龍辣條做爲報酬。小紅經不住誘惑,答應了。

回看一下上一章的代碼,咱們發現小紅牌超級計算器的add方法須要的參數是兩個整型變量和一個Student對象,可是老婆婆她不是學生,是個小商販啊,這裏確定要作修改。這種狀況下,咱們很天然的會想到繼承和多態。若是讓小明這個學生和老婆婆這個小商販從一個父類進行繼承,那麼咱們只須要給小紅牌超級計算器傳入一個父類的引用就能夠啦。

不過,實際使用中,考慮到java的單繼承,以及不但願把自身太多東西暴漏給別人,這裏使用從接口繼承的方式配合內部類來作。

換句話說,小紅但願之後繼續向班裏的小朋友們提供計算服務,同時還能向老婆婆提供算帳服務,甚至之後可以拓展其餘人的業務,因而她向全部的顧客約定了一個辦法,用於統一的處理,也就是本身須要的操做數和作完計算以後應該怎麼作。這個統一的方法,小紅作成了一個接口,提供給了你們,代碼以下:

1 public interface doJob
2 {
3     public void fillBlank(int a, int b, int result);
4 }

由於靈感來自幫小明填空,所以小紅保留了初心,把全部業務都當作填空(fillBlank)來作。

同時,小紅修改了本身的計算器,使其能夠同時處理不一樣的實現了doJob接口的人,代碼以下:

複製代碼
1 public class SuperCalculator
2 {
3     public void add(int a, int b, doJob  customer)
4     {
5         int result = a + b;
6         customer.fillBlank(a, b, result);
7     }
8 }
複製代碼

小明和老婆婆拿到這個接口以後,只要實現了這個接口,就至關於按照統一的模式告訴小紅獲得結果以後的處理辦法,按照以前說的使用內部類來作,代碼以下:

小明的:

複製代碼
 1 public class Student
 2 {
 3     private String name = null;
 4 
 5     public Student(String name)
 6     {
 7         // TODO Auto-generated constructor stub
 8         this.name = name;
 9     }
10     
11     public void setName(String name)
12     {
13         this.name = name;
14     }
15     
16     public class doHomeWork implements doJob
17     {
18 
19         @Override
20         public void fillBlank(int a, int b, int result)
21         {
22             // TODO Auto-generated method stub
23             System.out.println(name + "求助小紅計算:" + a + " + " + b + " = " + result);
24         }
25         
26     }
27     
28     public void callHelp (int a, int b)
29     {
30         new SuperCalculator().add(a, b, new doHomeWork());
31     }
32 }
複製代碼

老婆婆的:

複製代碼
 1 public class Seller
 2 {
 3     private String name = null;
 4 
 5     public Seller(String name)
 6     {
 7         // TODO Auto-generated constructor stub
 8         this.name = name;
 9     }
10     
11     public void setName(String name)
12     {
13         this.name = name;
14     }
15     
16     public class doHomeWork implements doJob
17     {
18 
19         @Override
20         public void fillBlank(int a, int b, int result)
21         {
22             // TODO Auto-generated method stub
23             System.out.println(name + "求助小紅算帳:" + a + " + " + b + " = " + result + "元");
24         }
25         
26     }
27     
28     public void callHelp (int a, int b)
29     {
30         new SuperCalculator().add(a, b, new doHomeWork());
31     }
32 }
複製代碼

測試程序以下:

複製代碼
 1 public class Test
 2 {
 3     public static void main(String[] args)
 4     {
 5         int a = 56;
 6         int b = 31;
 7         int c = 26497;
 8         int d = 11256;
 9         Student s1 = new Student("小明");
10         Seller s2 = new Seller("老婆婆");
11         
12         s1.callHelp(a, b);
13         s2.callHelp(c, d);
14     }
15 }
複製代碼

運行結果以下:

小明求助小紅計算:56 + 31 = 87
老婆婆求助小紅算帳:26497 + 11256 = 37753元

最後的話

能夠很明顯的看到,小紅已經把這件事情當作一個事業來作了,看她給接口命的名字doJob就知道了。

有人也許會問,爲何老婆婆擺攤能掙那麼多錢? 你的關注點有問題好嗎!!這裏聊的是回調機制啊!!

我只知道,後來小紅的業務不斷擴大,終於在幼稚園畢業以前,用掙到的錢買了人生的第一套房子。

完!!!

相關文章
相關標籤/搜索