java 回调(callback)函数简介.
一, 什么是回調函數(callback)
假如類A有1個方法a(), 但是它不知道什么時候調用這個方法a().
而類B告訴類A, 我知道什么時候調用.??? 那么類A就把自己交給類B(作為類B的一個成員),?? 當時機適合時, 類B會調用類A的a()方法.
那么a() 就叫回調(callback)方法.
可能我上面的解釋不夠好,
記住關鍵兩點就得了:
1. 類A 要成為類B的一個成員,??? java中是通過接口(interface)來實現的.
2. a()的執行由類B決定, 但是執行的是類A的方法a()
二, 什么要使用回調方法.
是啊, 為什么不直接使用類A來調用a()呢?
實際上這個也涉及層次的問題.
實際上, 類B可以調用類A的方法a(),?? 但是有時也可以調用其他比如類c的方法c(), 只要類c實現了接口, 替換成類B的成員.
也就是說, 客戶端只需要跟類B打交道, 無需知道實際執行的哪個類的哪個方法.
比如一個間公司有1個快遞部門(類B), 所有員工都可以找這個快遞部門寄快遞,?? 但是實際上這個部門是用順豐(類A)來快遞的.
但是當順豐快遞有問題時,? 類B也可以找另一間快遞公司,比如EMS(類C)來實現.
那么公司員工就不必與真正的快遞公司打交道, 只需把物件交給類B去處理就ok了. 也就是這個過程是動態的. 甚至也可以找另一件公司來實現(類D), 只需要類D實現快遞接口.
三, 基于上面快遞的一個具體例子
現在我們就基于上面的例子寫一段代碼.
3.1 UML圖
可以見上面有5中角色
分別是:
員工:? Employee
快遞部門: ExDepartment
回調(快遞)接口: Callbackable
具體快遞公司: SFExpress & EMS
下面是具體代碼:
3.2 Callbackable
這個接口只需要定義1個回調方法method()
public interface Callbackable {public void method(); }3.3 ExDepartment
同樣地, 快遞部門類必須預留1個接口成員.
它可以選擇1個實現了Callbackable接口的對象作為自己的成員,
public class ExDepartment {private Callbackable exCompany;public void setExCompany(Callbackable exCompany) {this.exCompany = exCompany;}public ExDepartment(Callbackable exCompany){this.setExCompany(exCompany);}public void sendGoods(){exCompany.method();} }這個部門有1個快遞方法sendGoods(), 但是實際上是調用這個快遞公司成員的回調方法.method();
3.4 SFExpress
具體的快遞公司類順豐, 必須實現Callbackable接口,
并重寫里面回調方法.
3.5 EMS
同上
public class EMS implements Callbackable {public void EMSSendGoods(){System.out.println("Sent GOods by EMS");}@Overridepublic void method() {// TODO Auto-generated method stubthis.EMSSendGoods();}}3.6 Employee
員工類, 無需知道具體快遞公司的存在, 只需要跟快遞部門打交道就ok了
public class Employee {public void sendGoods(ExDepartment exd){exd.sendGoods();} }3.7 客戶端代碼和輸出:
ExDepartment exd = new ExDepartment(new SFExpress());Employee jack = new Employee();jack.sendGoods(exd);exd.setExCompany(new EMS());jack.sendGoods(exd);exd.setExCompany(new Callbackable() {@Overridepublic void method(){System.out.println("Sent goods by Jimmy!");}});jack.sendGoods(exd);輸出:
Sent goods by SF! Sent GOods by EMS Sent goods by Jimmy!可以見到, 員工寄了3次快遞, 第一次是順豐, 第一次是EMS, 但是第三次是某個人(可能兩個快遞公司都放假, 隨便找個人來送)
這個模型的好處時,
無論有什么具體快遞類的修改, 只需要修改快遞類本身.
而增加快遞公司類, 只需讓那個類實現回調接口, 而員工類和快遞部門類都無需修改的.
四, java的控件事件方法也是用回調來實現的.
上面的代碼有這么一段:
exd.setExCompany(new Callbackable() {@Overridepublic void method(){System.out.println("Sent goods by Jimmy!");}});上面用到了內部類的方法.
是不是覺得有d面善.
這種寫法跟java的button事件定義優點類似.
下面是新建1個button的例子:
JButton btnNewButton = new JButton("New button");btnNewButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {}});其中btnNewButton就相當于上面例子的快遞部門ExDepartment
而ActionListener實際上就是1個回調接口. (在這里也叫監聽器)
而actionPerFormed就是1個回調方法.
沒錯, java界面(awt/swt)的控件事件就是通過回調來實現的.
你們想想, 一個button,? 按下去做什么不是固定的.
有的button觸發 行為a(), 有些觸發行為b()
所以, 我們讓行為b()寫成回調方法, 也就是所讓它所需的類實現 回調接口ActionListener().
這樣, 就可以很靈活地為每1個button定義不同的觸發行為了!
總結
以上是生活随笔為你收集整理的java 回调(callback)函数简介.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么有人说面向对象编程就是面向接口编程
- 下一篇: WebServer 软件原理简介