回调,在网上看了很多例子,也没有找到特别好的解释,基本上都是用自己的话,作了一个解释。在这里也想用自己的话,对回调作个简单的解释。回调,可能的字面理解:回过头来调用,比如说,有类A,里面有方法B,调用类A得B方法,但是B方法的实现却是调用了类C的D方法,但是在D方法的内部又调用了类A的E方法。此时的E方法称为回调方法。
接下来,我们来分析分析上面提到的这句话。类A的B方法能够调用类C的D方法,只需要在类A中持有一个类C的引用即可,这样就可以调用类C的方法了,还不仅仅是D这一个方法。但问题就来了,在类C的方法D中,它是如何做到调用类A得E方法的???其中有一个解决办法,就是在类C中也可以持有一个类A得引用,如果这么做的话,功能上的确可以做到,但显然不是这么实现的,那究竟是怎么实现的呢?答案是这样的,就是在类A得B方法在调用类C得D方法时,把要调用的类A得E方法给传过去,问题就可以解决了。
现在来举个例子来说明下上面提到的。
比如说,有两个学生小明和小红,当时都在学习加法运算,突然有一天,小红突然向小明请问,一加一等于二,那二加二是不是等于三啊,当时小明心头一惊,我擦,这题目有点小难度啊 ,但直接开口说不会,这尼玛太丢人了,这要是被别人知道了,这还怎么在江湖上混,然后略一沉思后,对小红说,这样,我现在有点忙(实际上,要去找外援),等下再告诉你答案好吧,然后小红就愉快的答应了,还加了句,知道答案了,记得打电话告诉我啊,爱你,么么哒。
现在我们用代码来模拟这个过程。其中类XiaoHong代表小红,类XiaoMing代表小明,具体实现如下:
类XiaoMing
package cn.ccnu.callback.demo;
public class XiaoMing {
public void answerQuestion(int a, int b){
System.out.println("外援寻找过程中。。。。。。哇,我知道答案了......");
int result = a + b;
System.out.println(a + " + " + b + " = " + result);
}
}
其中类小明有一个回答问题的方法answerQuestion方法,可以帮小红来回答关于加法的问题。
类XiaoHong
package cn.ccnu.callback.demo;
public class XiaoHong {
//持有一个对小明的引用
private XiaoMing xiaoMing;
public XiaoHong(XiaoMing xiaoMing){
this.xiaoMing = xiaoMing;
}
public void askQuestion(int a, int b){
xiaoMing.answerQuestion(a, b);
}
}
其中类小红持有一个对类小明的引用和一个问问题的方法askQuestion方法,然后问题就被勤劳的小明被回答了。
我们来测试下,小明能不能来回答小红的问题。
测试
package cn.ccnu.callback.demo;
import org.junit.Test;
public class DemoTest {
@Test
public void test1(){
XiaoMing xiaoMing = new XiaoMing();
XiaoHong xiaoHong = new XiaoHong(xiaoMing);
xiaoHong.askQuestion(2, 2);
}
}
答案是小明回答的非常完美。但由于小红说了,回答完后,你要告诉我哦,告诉我啊,告诉我哦,小明懵逼了,这怎么告诉你啊,小红说,我把我的手机号码告诉你吧,这样你就可以告诉我,你知道二加二等于几了。这里的在回答完问题后,还告诉小红我回答问题了的方式,其实就是回调了,怎么回调的呢,就是调用类小红里面的一个方法,那问题就来了,类小明没有持有类小红的引用啊,难道类小明是神仙,掐指一算,就知道那个要调用的方法长什么样?答案肯定是否定的,要是小明真有这个能力,也就不会被黑这么久了,既然这样,那又是怎么做到的呢?就是在小红在调用askQuestion这个方法的时候,把要调用的类小红的方法作为一个接口传进去,这样小明就知道了要调用的那个方法长什么样了。看代码。
在类小红中添加一个方法inform给类小明调用,以用来通知小红,你的问题我已经回答了。
package cn.ccnu.callback.demo;
public class XiaoHong implements Message{
//持有一个对小明的引用
private XiaoMing xiaoMing;
public XiaoHong(XiaoMing xiaoMing){
this.xiaoMing = xiaoMing;
}
public void askQuestion(int a, int b){
xiaoMing.answerQuestion(a, b, this);
}
public void inform(){
System.out.println("亲爱的小明,我已经收到你的答案了,么么哒。。。。。。");
}
}
虽然小红是添加了这个方法,但实际上小明是想调但也调不了啊,于是把这个inform抽象出一个接口。
package cn.ccnu.callback.demo;
public interface Message {
public void inform();
}
接下来,我们再重新改造下我们类小明的answerQuestion方法,不是原来那个只有两个参数的方法了,不是要我通知你们,那就再加个参数吧。便于我通知你们啊,谁叫我是雷锋了,做了事,还得告诉你们,我做完了。
package cn.ccnu.callback.demo;
public class XiaoMing {
public void answerQuestion(int a, int b, Message message){
System.out.println("外援寻找过程中。。。。。。哇,我知道答案了......");
int result = a + b;
System.out.println(a + " + " + b + " = " + result);
message.inform();
}
}
最后,我们测试下,看好不好使。
package cn.ccnu.callback.demo;
import org.junit.Test;
public class DemoTest {
@Test
public void test1(){
XiaoMing xiaoMing = new XiaoMing();
XiaoHong xiaoHong = new XiaoHong(xiaoMing);
xiaoHong.askQuestion(2, 2);
}
}
很显然的是,小明帮小红回答了问题,然后还告诉了小红,这题我真会做啊,我做完了。
以上就是我对回调的一些理解,如有不对,还望指正,自己在网上看了很多帖子,怕自己忘记,又自己总结了一遍。