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

来源:互联网 发布:do是java关键字 编辑:程序博客网 时间:2024/06/03 05:55

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

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


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


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

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

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

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

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{@Overridepublic 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方法了
是不是非常的方便呢




1 0
原创粉丝点击