您的位置:首页 > 移动开发 > Android开发

什么是回调函数?如何运用?

2016-03-29 17:19 666 查看
在使用开源项目的时候经常会使用到回调函数,如果把回调函数弄清楚了,那么对我们深入了解开源项目会有很大帮助。

回调函数百度百科的解释:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

看上去不是那么容易理解,我们来看个例子(知乎):

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

这样好理解多了吧,当店员被创建出来的时候,并不知道有谁会来商店里买东西,店员需要和很多不同的对象打交道,需要适配不同类型的对象,这个时候就需要回调函数了。

我们通过一个事例来理解一下回调函数的运用场景:

Me需要完成一个任务,计算1+1=?

Me如果要自己完成这个任务

代码如下

public class Me{

public void getAnswer(String ques){
if(ques.equals("1+1=?")){
System.out.println("问题:" + ques + "答案:" + 2);
}else{
System.out.println("问题:" + ques + "答案:" + "额...");
}
}

public static void main(String[] args) {
Me m = new Me();

String ques = "1+1=?";
m.getAnswer(ques);
}

}


执行结果

问题:1+1=?答案:2

这个时候问题的处理逻辑都是在Me类中的

如果Me不想自己做,想要找个人帮他完成这个任务时该怎么办呢

代码如下

public class Me{

public void getAnswer(String ques, String answer){
if(answer != null){
System.out.println("问题:" + ques + "答案:" + answer);
}
}

public static void main(String[] args) {
Me m = new Me();
HelpPerson hp = new HelpPerson();

String ques = "1+1=?";
String answer = hp.getAnswer(ques);
m.getAnswer(ques, answer);
}

}
帮助他的HelpPerson

public class HelpPerson {

public String getAnswer(String ques){
if(ques.equals("1+1=?")){
return "2";
}else{
return "额...";
}
}
}


执行结果

问题:1+1=?答案:2

到目前为止我们还没有运用到回调方法,那么哪种情况下需要运用到回调方法呢?

发现了上面的代码问题吗?帮助Me的HelpPerson只提供出了答案,但最终还是要在Me中调用自己的方法才能提交(显示)出来。

那么如何避免这样的现象,让Me更轻松呢

可以让HelpPerson帮忙调用Me中的getAnswer方法

代码如下

public class Me{

public void getAnswer(String ques, String answer){
if(answer != null){
System.out.println("问题:" + ques + "答案:" + answer);
}
}

public static void main(String[] args) {
Me m = new Me();
HelpPerson hp = new HelpPerson();

String ques = "1+1=?";
hp.getAnswer(ques, m);
}

}
public class HelpPerson {

public void getAnswer(String ques, Me m){
if(ques.equals("1+1=?")){
m.getAnswer(ques, "2");
}else{
m.getAnswer(ques, "额...");
}
}
}


执行结果

问题:1+1=?答案:2

Me调用了HelpPerson中帮忙完成任务的方法,并且传递了一个自己的引用过去,HelpPerson帮忙得到答案后顺便调用了Me方法里的提交(显示)方法,最终完成了任务

这就是简单的回调了

需要注意的是,在调用方法的时候传递自己的引用过去是十分不妥的

实际开发中也不应该出现这样的代码

还有就是传入的一个具体的引用,那么HelpPerson就只能给Me提供服务了,如果其它对象也需要同样的请求怎么办?总不可能又再建一个方法,改变一下引用吧?

这时候我们就需要用到接口了

建立一个接口,规定需要什么东西才能完成任务,比如这里就需要问题,和答案

代码如下

public interface DoQuesAnswerImp {
void getQuesAnswer(String ques, String answer);
}
修改HelpPerson中的引用

public class HelpPerson {

public void getAnswer(String ques, DoQuesAnswerImp dqai){
if(ques.equals("1+1=?")){
dqai.getQuesAnswer(ques, "2");
}else{
dqai.getQuesAnswer(ques, "额...");
}
}
}
public class Me implements DoQuesAnswerImp{

@Override
public void getQuesAnswer(String ques, String answer) {
if(answer != null){
System.out.println("问题:" + ques + "答案:" + answer);
}
}

public static void main(String[] args) {
Me m = new Me();
HelpPerson hp = new HelpPerson();

String ques = "1+1=?";
hp.getAnswer(ques, m);
}
}
执行结果

问题:1+1=?答案:2

这样,HelpPerson中的getAnswer方法不用传入具体的引用了

只要是实现了DoQuesAnswerImp接口的对象都可以调用HelpPerson中的getAnswer方法了

是不是非常的方便呢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息