java什么是回調(diào)
軟件模塊之間總是存在著一定的接口,從調(diào)用方式上,可以把他們分為三類:同步調(diào)用、回調(diào)和異步調(diào)用。同步調(diào)用是一種阻塞式調(diào)用,調(diào)用方要等待對(duì)方執(zhí)行完畢才返回,它是一種單向調(diào)用;回調(diào)是一種雙向調(diào)用模式,也就是說,被調(diào)用方在接口被調(diào)用時(shí)也會(huì)調(diào)用對(duì)方的接口;異步調(diào)用是一種類似消息或事件的機(jī)制,不過它的調(diào)用方向剛好相反,接口的服務(wù)在收到某種訊息或發(fā)生某種事件時(shí),會(huì)主動(dòng)通知客戶方(即調(diào)用客戶方的接口)?;卣{(diào)和異步調(diào)用的關(guān)系非常緊密,通常我們使用回調(diào)來實(shí)現(xiàn)異步消息的注冊(cè),通過異步調(diào)用來實(shí)現(xiàn)消息的通知。同步調(diào)用是三者當(dāng)中最簡(jiǎn)單的,而回調(diào)又常常是異步調(diào)用的基礎(chǔ),因此,下面我們著重討論回調(diào)機(jī)制在不同軟件架構(gòu)中的實(shí)現(xiàn)。
Java的回調(diào)簡(jiǎn)單的說,回調(diào)函數(shù)就是通過其指針來調(diào)用的函數(shù)(這句話確實(shí)夠簡(jiǎn)單的,下面會(huì)詳細(xì)的描述);回調(diào)函數(shù)不會(huì)被自己所在的對(duì)象調(diào)用,只會(huì)在調(diào)用別人的方法的時(shí)候反過來被調(diào)用。我們知道android程序是通過java來實(shí)現(xiàn)的,java中是沒指針的,那么怎么實(shí)現(xiàn)回調(diào)呢,通過接口、或者抽象類。
實(shí)現(xiàn)步驟:
1、定義一個(gè)接口,其中包含一個(gè)方法a;
2、定義一個(gè)實(shí)現(xiàn)這個(gè)接口的類A,實(shí)現(xiàn)方法 a(此處的a就是傳說中的回調(diào)函數(shù),此處不一定要在聲明類的時(shí)候?qū)崿F(xiàn)這個(gè)接口,也可以在類中去實(shí)現(xiàn)這個(gè)接口,我會(huì)分別舉例子)
3、定義一個(gè)類B,在B中定義一個(gè)方法b,b以第一步中定義的接口作為參數(shù);
4、在A中調(diào)用方法b,把自己作為參數(shù)傳遞進(jìn)去;
5、在B中通過傳遞進(jìn)來的參數(shù)A(實(shí)現(xiàn)了接口)去調(diào)用a,這就實(shí)現(xiàn)了回調(diào);
至于為什么要使用回調(diào)函數(shù)呢?在一位大神的博客里面看到這句話“回調(diào)功能是實(shí)現(xiàn)功能和定義分離的一種手段,是一種松耦合的設(shè)計(jì)思想”,有的人就會(huì)問了,為什么要實(shí)現(xiàn)定義和功能分離呢?我們?cè)趧傞_始接觸面向?qū)ο蟮倪@個(gè)概念的時(shí)候,應(yīng)該經(jīng)常聽到這種說法:面向?qū)ο笫且獙?shí)現(xiàn)高內(nèi)聚、低耦合,方便程序的修改和擴(kuò)展。我覺得函數(shù)的定義和功能的分離應(yīng)該也是這個(gè)道理吧。在下面的例子中我會(huì)在注釋中從另外一個(gè)方面說明回調(diào)函數(shù)的必要性。
其次,看代碼吧
代碼1,在聲明類的時(shí)候?qū)崿F(xiàn)接口:
[java] view plaincopypackage com.callback;
/* 第一步:定義一個(gè)接口,其中包含一個(gè)方法a*/
public interface Callback {
public void a(int i);
}
[java] view plaincopypackage com.callback;
/* 第二步:定義一個(gè)實(shí)現(xiàn)這個(gè)接口的類A,實(shí)現(xiàn)方法 a*/
public class A implements Callback{
static B b = new B();
/* 此處為什么要定義一個(gè)常量呢?
* 我是想從另一個(gè)方面(松耦合的設(shè)計(jì)思想算是一方面吧)說明回調(diào)方法的必要性,
* 暫時(shí)先不用管,后面會(huì)繼續(xù)說明的*/
final int Constant = 1;
@Override
/* 回調(diào)方法不會(huì)在A類中被調(diào)用的,注意看待會(huì)他會(huì)在哪被調(diào)用 */
public void a(int result) {
// TODO Auto-generated method stub
System.out.println(result);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
/* 第四步:在A中調(diào)用方法b,把自己作為參數(shù)傳遞進(jìn)去,
* 此處A中的常量Constant,也會(huì)隨著A被傳到B中*/
b.b(new A());
}
}