搜尋
首頁Javajava教程詳解 JAVA的回呼機制CallBack

序言

CallBack是回呼的意思,熟悉Windows程式設計的人對"回呼函數"這四個字一定不會陌生,但是Java程式設計師對它可能就不太了解了。 "回呼函數"或"回呼方法"是軟體設計與開發中一個非常重要的概念,掌握"回呼函數"的思想對程式設計師來說(不管用哪種語言)是非常必要的。

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

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

第1章. 故事的緣起

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

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

public class Student
{
private String name = null;
public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
private int calcADD(int a, int b)
{
return a + b;
}
public void fillBlank(int a, int b)
{
int result = calcADD(a, b);
System.out.println(name + "心算:" + a + " + " + b + " = " + result);
}
}

小明同學在填空(fillBalnk)的時候,直接心算(

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

public class Test
{
public static void main(String[] args)
{
int a = ;
int b = ;
Student s = new Student("小明");
s.fillBlank(a, b);
}
}


運作結果如下:


小明心算:1 + 1 = 2 


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

第2章. 幼師的找茬


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


花擦!為什麼所有老師都跟小明過不去啊?明明超綱了好不好!這時候小明同學明顯不能再像上面那樣靠心算來完成了,正在懵逼的時候,班上的小紅同學遞過來一個只能計算加法的計算器(奸商啊)! ! ! !而小明同學剛好知道怎麼用計算器,於是透過計算機計算得到結果並完成了填空。

計算器的程式碼為:

public class Calculator
{
public int add(int a, int b)
{
return a + b;
}
}

修改Student類,加入使用計算機的方法:

public class Student
{
private String name = null;
public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
@SuppressWarnings("unused")
private int calcADD(int a, int b)
{
return a + b;
}
private int useCalculator(int a, int b)
{
return new Calculator().add(a, b);
}
public void fillBlank(int a, int b)
{
int result = useCalculator(a, b);
System.out.println(name + "使用计算器:" + a + " + " + b + " = " + result);
}
}

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

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

3. 幼師回來了


發現小明完成了3位數的加法,​​老師覺得小明很聰明,是個可塑之才。於是又在黑板上寫下了“26549 + 16487 = ”,讓小明上課前完成填空,然後又回辦公室了。


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


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


這裡,不把小紅單獨實現出來,而是把這個只能算加法的計算器和小紅看成一個整體,一個會算結果還會填空的超級計算器。這個超級計算器需要傳的參數是兩個加數和要填空的位置,而這些內容需要小明提前告知,也就是小明要把自己的一部分方法暴漏給小紅,最簡單的方法就是把自己的引用和兩個加數一塊告訴小紅。


因此,超級計算器的add方法應該包含兩個操作數和小明自身的引用,程式碼如下:

public class Test
{
public static void main(String[] args)
{
int a = ;
int b = ;
Student s = new Student("小明");
s.fillBlank(a, b);
}
}

小明這邊現在已經不需要心算,也不需要使用計算器了,因此只需要有一個方法可以向小紅尋求幫助就行了,程式碼如下:

public class SuperCalculator
{
public void add(int a, int b, Student xiaoming)
{
int result = a + b;
xiaoming.fillBlank(a, b, result);
}
}

   


測試程式碼如下:

public class Student
{
private String name = null;
public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, this);
}
public void fillBlank(int a, int b, int result)
{
System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
}
}

   

1757627627672767237672000322:00176299:03876272729283232323233分7: 計算小= 43036 

執行流程為:小明透過自身的callHelp方法呼叫了小紅(new SuperCalculator())的add方法,在呼叫的時候將自身的引用

(this)當做參數一併傳入,小紅在使用計算機得出結果之後,回調了小明的fillBlank方法,將結果填在了黑板上的空格里。

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

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

第4章. 門口的婆婆

幼稚园的门口有一个头发花白的老婆婆,每天风雨无阻在那里摆着地摊卖一些快过期的垃圾食品。由于年纪大了,脑子有些糊涂,经常算不清楚自己挣了多少钱。有一天,她无意间听到了小明跟小伙伴们吹嘘自己如何在小红的帮助下与幼师斗智斗勇。于是,婆婆决定找到小红牌超级计算器来做自己的小帮手,并提供一包卫龙辣条作为报酬。小红经不住诱惑,答应了。

回看一下上一章的代码,我们发现小红牌超级计算器的add方法需要的参数是两个整型变量和一个Student对象,但是老婆婆她不是学生,是个小商贩啊,这里肯定要做修改。这种情况下,我们很自然的会想到继承和多态。如果让小明这个学生和老婆婆这个小商贩从一个父类进行继承,那么我们只需要给小红牌超级计算器传入一个父类的引用就可以啦。

不过,实际使用中,考虑到java的单继承,以及不希望把自身太多东西暴漏给别人,这里使用从接口继承的方式配合内部类来做。

换句话说,小红希望以后继续向班里的小朋友们提供计算服务,同时还能向老婆婆提供算账服务,甚至以后能够拓展其他人的业务,于是她向所有的顾客约定了一个办法,用于统一的处理,也就是自己需要的操作数和做完计算之后应该怎么做。这个统一的方法,小红做成了一个接口,提供给了大家,代码如下:

public interface doJob
{
public void fillBlank(int a, int b, int result);
}

因为灵感来自帮小明填空,因此小红保留了初心,把所有业务都当做填空(fillBlank)来做。

同时,小红修改了自己的计算器,使其可以同时处理不同的实现了doJob接口的人,代码如下:

public class SuperCalculator
{
public void add(int a, int b, doJob customer)
{
int result = a + b;
customer.fillBlank(a, b, result);
}
}

   

小明和老婆婆拿到这个接口之后,只要实现了这个接口,就相当于按照统一的模式告诉小红得到结果之后的处理办法,按照之前说的使用内部类来做,代码如下:

小明的:

public class Student
{
private String name = null;
public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public class doHomeWork implements doJob
{
@Override
public void fillBlank(int a, int b, int result)
{
// TODO Auto-generated method stub
System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
}
}
public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, new doHomeWork());
}
}

   

老婆婆的:

public class Seller
{
private String name = null;
public Seller(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public class doHomeWork implements doJob
{
@Override
public void fillBlank(int a, int b, int result)
{
// TODO Auto-generated method stub
System.out.println(name + "求助小红算账:" + a + " + " + b + " = " + result + "元");
}
}
public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, new doHomeWork());
}
}

   

测试程序如下:

public class Test
{
public static void main(String[] args)
{
int a = ;
int b = ;
int c = ;
int d = ;
Student s = new Student("小明");
Seller s = new Seller("老婆婆");
s.callHelp(a, b);
s.callHelp(c, d);
}
}

运行结果如下:

小明求助小红计算:56 + 31 = 87

老婆婆求助小红算账:26497 + 11256 = 37753元 

最后的话

可以很明显的看到,小红已经把这件事情当做一个事业来做了,看她给接口命的名字doJob就知道了。

更多详解 JAVA的回调机制CallBack相关文章请关注PHP中文网!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

如何將Java的RMI(遠程方法調用)用於分佈式計算?如何將Java的RMI(遠程方法調用)用於分佈式計算?Mar 11, 2025 pm 05:53 PM

本文解釋了用於構建分佈式應用程序的Java的遠程方法調用(RMI)。 它詳細介紹了接口定義,實現,註冊表設置和客戶端調用,以解決網絡問題和安全性等挑戰。

如何使用Java的插座API進行網絡通信?如何使用Java的插座API進行網絡通信?Mar 11, 2025 pm 05:53 PM

本文詳細介紹了用於網絡通信的Java的套接字API,涵蓋了客戶服務器設置,數據處理和關鍵考慮因素,例如資源管理,錯誤處理和安全性。 它還探索了性能優化技術,我

如何在Java中創建自定義網絡協議?如何在Java中創建自定義網絡協議?Mar 11, 2025 pm 05:52 PM

本文詳細介紹了創建自定義Java網絡協議。 它涵蓋協議定義(數據結構,框架,錯誤處理,版本控制),實現(使用插座),數據序列化和最佳實踐(效率,安全性,維護

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具