百度百科定義:
回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數地址給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。
回調函數和普通函數的區別
程序員調用第三方的函數,是直調,第三方的函數是普通函數;
第三方寫好通用模塊代碼,但在某些差異性比較大的代碼留空,讓程序員填充自己想要的功能。這樣代碼運行的流程就是:程序員調用第三方的代碼——>第三方代碼執行通用模塊代碼并在差異性留空的地方調用程序員自己寫的代碼。則第三方調用程序員的代碼就是回調,程序員寫的關鍵部分的代碼就叫做回調函數。
C語言的回調函數和java的接口回調是一個意思,只是語言描述不同,前者用函數指針實現,后者用接口實現。
例子:programfunc()調用systemfunc(),systemfunc()為普通函數
(1)普通函數:
void programfunc(){//程序員寫的函數
systemfunc();//程序員寫的函數里調用系統函數
doOtherthing…;
}
//第三方函數
void systemfunc(){
doSomething…;
}
(2)回調函數
//程序員編寫的函數
void programfunc(){
doOtherthing…;
}
//第三方函數
void systemfunc(void(*p)()){
doSomething…;
p();//回調程序員寫的函數
}
//主函數
void main(){
int (*func)();? //函數指針
func?=?programfunc;
systemfunc(func?);
}
為什么要需要接口回調
個人認為,接口回調的目的是讓代碼因場景而變通,換句話說是使得第三方的代碼更加具有通用性。
比如,在安卓開發中,app的按鍵按下之后可能會有不同的響應,如按鍵1按下之后是撥打電話,按鍵2按下之后之后是發送短信。二者在代碼實現上的共同點是判斷按鍵按下,差異是按下之后執行的操作不同。所以系統先寫好判斷按鍵按下的代碼,程序員只需要讓對應的組件實現OnClickListener接口,重寫onclick方法即可。
為什么不使用繼承而使用接口
前面提到接口回調的目的是實現多樣性,那為什么不使用繼承并重寫對應的方法呢。原因是java為了降低復雜性,一個類只能單繼承,不能多繼承,但可以實現多個接口。
多繼承容易造成代碼混亂,比較燒腦。比如,A類,B類中都有一個helloworld方法。如果C類多繼承A和B,那么C類的helloworld方法有可能來自A類,又有可能來自B類,就會造成沖突。當項目龐大的時候,容易增加復雜性。
而接口只是聲明方法,并不能具體實現,所以允許多接口。