百度百科定义:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数地址给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
回调函数和普通函数的区别
程序员调用第三方的函数,是直调,第三方的函数是普通函数;
第三方写好通用模块代码,但在某些差异性比较大的代码留空,让程序员填充自己想要的功能。这样代码运行的流程就是:程序员调用第三方的代码——>第三方代码执行通用模块代码并在差异性留空的地方调用程序员自己写的代码。则第三方调用程序员的代码就是回调,程序员写的关键部分的代码就叫做回调函数。
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类,就会造成冲突。当项目庞大的时候,容易增加复杂性。
而接口只是声明方法,并不能具体实现,所以允许多接口。