1. 程式人生 > >JAVA回撥機制(CallBack)詳解

JAVA回撥機制(CallBack)詳解

轉載地址:http://www.cnblogs.com/heshuchao/p/5376298.html

序言

最近學習java,接觸到了回撥機制(CallBack)。初識時感覺比較混亂,而且在網上搜索到的相關的講解,要麼一言帶過,要麼說的比較單純的像是給CallBack做了一個定義。當然了,我在理解了回撥之後,再去看網上的各種講解,確實沒什麼問題。但是,對於初學的我來說,缺了一個循序漸進的過程。此處,將我對回撥機制的個人理解,按照由淺到深的順序描述一下,如有不妥之處,望不吝賜教!

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

第1章. 故事的緣起

幼師在黑板上寫一個式子 “1 + 1 = ”,由小明同學來填空。

由於已經學習了10以內的加法,小明同學可以完全靠自己來計算這個題目,模擬該過程的程式碼如下:

複製程式碼
 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,並將結果寫在空格里。測試程式碼如下:

複製程式碼
 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 }
複製程式碼

執行結果如下:

小明心算:1 + 1 = 2

該過程完全由Student類的例項物件單獨完成,並未涉及回撥機制。

第2章. 幼師的找茬

課間,幼師突發奇想在黑板上寫了“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 
            
           

相關推薦

JAVA機制(CallBack)

轉載地址:http://www.cnblogs.com/heshuchao/p/5376298.html 序言 最近學習java,接觸到了回撥機制(CallBack)。初識時感覺比較混亂,而且在網上搜索到的相關的講解,要麼一言帶過,要麼說的比較單純的像是給CallBa

函式機制、非同步函式機制圖例

函式回撥機制,一種雙向呼叫思想,簡單來說就是,如下圖所示:            在層次一中的方法一(函式)呼叫層次二中的方法,並傳入函式二的地址,而這個被呼叫的方法又會呼叫層次一中的方法,這個最後被

java機制

原文出自這兒:https://blog.csdn.net/fengye454545/article/details/80198446   為了自己能夠加深理解自己動手敲了一遍,也寫寫,有時間看看。更詳細建議訪問原創博主。 ===========================

Java機制的學習(CallBack)

深入淺出的理解Java回撥機制(一個有趣的小例子): http://www.cnblogs.com/heshuchao/p/5376298.html Java同步呼叫,非同步呼叫,回撥(參考) https://www.cnblogs.com/xrq730/p/6424471.html

java機制用的理解與例項

生活場景如下: Wang寫數學題,有一道比較難,需要問Li,Li也不會,要先回家一趟問問老爸怎麼做,這個時候有wang如下三種選擇: 1)一直等待Li回來,期間啥也不幹同步方式 2) 等等再過來看Li回來沒,非同步future方式 3)wang把電話留下來,讓LI回來時打電話給自

一個經典例子讓你徹徹底底理解java機制

                以前不理解什麼叫回調,天天聽人家說加一個回撥方法啥的,心裡想我草,什麼叫回調方法啊?然後自己就在網上找啊找啊找,找了很多也不是很明白,現在知道了,所謂回撥:就是A類中呼叫B類中的某個方法C,然後B類中反過來呼叫A類中的方法D,D這個方法就叫回調方法,這樣子說你是不是有點暈暈的,

深入淺出: Java機制(非同步)

Writer      :李強強 什麼是回撥?今天傻傻地截了張圖問了下,然後被陳大牛回答道“就一個回撥…”。此時千萬個草泥馬飛奔而過(逃 哈哈,看著原始碼,享受著這種回撥在程式碼上的作用,真是美哉。不妨總結總結。 一、什麼是回撥 回撥,回撥。要先有呼叫,才有呼叫者和被呼叫者之間的回撥。所以在百

[Java]機制

現有A、B兩個類,兩個類的例項a、b,A中實現a()方法,B中實現b()方法。 回撥要求物件a在呼叫b物件的b()方法時,b()方法返回前需呼叫物件a的a()方法。 以管道通訊傳輸為例,程式需要一邊不停接收對端傳來的資料並將接收到的資料進行處理,而又不影響主執行緒的進行。  

Java基礎9——深入理解java機制

Java回撥機制 回撥的引入故事 轉載自Bro_超 // 同步回撥 1 public interface doJob 2 { 3 public void fillBlank(int a, int b, int result); 4 } 1 public class Su

Java機制(非同步)

什麼是回撥?今天傻傻地截了張圖問了下,然後被陳大牛回答道“就一個回撥…”。此時千萬個草泥馬飛奔而過(逃 哈哈,看著原始碼,享受著這種回撥在程式碼上的作用,真是美哉。不妨總結總結。 一

Activity被回收掉之後的網路請求處理方法

想起寫這麼一篇博文的前提是上週去面試了一家公司,其中有這麼一個問題印象深刻,結合當時在網上看到的解決辦法我就說了一個錯誤答案,結果當場就被面試官給指出了錯誤,所以回來後和我的領導一起討論了這麼一個問題,他提出了一個很好地解決思路,於是乎我便寫了這麼一段程式

java機制經典例子

以前不理解什麼叫回調,天天聽人家說加一個回撥方法啥的,心裡想我草,什麼叫回調方法啊?然後自己就在網上找啊找啊找,找了很多也不是很明白,現在知道了,所謂回撥:就是A類中呼叫B類中的某個方法C,然後B類中反過來呼叫A類中的方法D,D這個方法就叫回調方法,這樣子說你是不

Java 函式callback 用法

1.定義回撥函式介面裡面包含一個方法public interface CallBack { public void execute(); }2.定義回撥函式的實現 public class Bo

Java機制在Android中的應用

一、前言 1.回撥定義 就是A類中呼叫B類中的某個方法C,然後B類中反過來呼叫A類中的方法D,D這個方法就叫回調方法 2.經典的回撥方式: ● Class A實現介面CallBack callback——背景1 ● class A中包含一個

Android開發中Java機制的應用

  用Java寫了這麼久的程式,一直沒有理解什麼是回撥,在最近的Android開發工作中,一個偶然的需求讓我突然就對Java中的回撥有了一個理解,遂記錄之。   首先這個需求是這樣的,一個Activity中的有一個View,我需要在不同的觸發條件下更換這個View的Lay

淺談Java機制

回撥機制讓我們程式碼執行更加高效,也讓我們程式碼變得非常的簡潔明瞭! 首先我們用個案例來一步一步帶入,當我們需要解析一段JSON字串時大部分我們的操作就是: public class ParseJS

Java機制解析

模組之間總是存在這一定的介面,從呼叫方式上看,可以分為三類:同步呼叫、回撥和非同步呼叫。同步呼叫是一種阻塞式呼叫,也是我們在寫程式中經常使用的;回撥是一種雙向的呼叫模式,也就是說,被呼叫的介面被呼叫時也會呼叫對方的介面,這句話可能有點繞,等文章後面舉例說明;非同步呼叫是一種類似訊息或事件的機制,解決了同步

Java機制與OOP思想

結合Java的回撥機制總結OPP的思想,因為Java是自學的,開始抽象類和介面的概念都能理解,別人用也能懂,但等到自己設計的時候總是很生疏,等到做Android時,不停的回撥,回撥,回撥。。。看看原始碼,一點點的就有了理解,就此來總結一下,有不對的地方還請多指出評批。 語言

Java機制(以Android事件監聽器為例)

Java的設計模式中有回撥這個機制,在Android開發中我們也會經常用到回撥機制。下面就通過一些小例子來說明什麼是回撥。 假如我們要實現這個這樣一個功能。 MainActivity中由一個Fragment和一個ViewPager構成,Fragment中有一系列按鈕,通過

一個經典的例子讓你徹底理解Java機制

以前不理解什麼叫回調,天天聽人家說加一個回撥方法啥的,心裡想我草,什麼叫回調方法啊?然後自己就在網上找啊找啊找,找了很多也不是很明白,現在知道了,所謂回撥:就是A類中呼叫B類中的某個方法C,然後B類中反過來呼叫A類中的方法D,D這個方法就叫回調方法,這樣子說你是不是有點暈暈的,其實我剛開始也是這樣不理解,