一:回调:比如说:
张三和李四是好朋友,一天张三遇到一个问题需要李四帮忙计算一下,此时张三就给李四打电话,说 “李四,我是张三,我有一个问题请教你帮我计算一下?”,此时李四就开始计算此问题,计算完问题后就给张三打电话告诉他答案。李四打电话告诉张三答案的过程就是一个回调过程。
二:定义一个借口CallBack(其实不定义借口也可以,但是扩展性不好,结果的好处就是扩展性)。
把回调方法放在接口中(回调方法必须放在接口中)(多态)。
三:张三李四必须实现Callback接口。
张三向李四问问题,所以张三必须有一个李四的引用,张三类成员有:张三必须有一个提问题的方法,在提问题的方法中让李四给计算问题。
而李四必须有一个计算问题的方法,方法中必须接受一个CallBack的实例(此实例就是张三的实例,利用张三的实例完成回调),在李四解决问题之后用传过来的CallBack实例去调用回调方法即可。
四: 代码如下:
public interface CallBack {
public void solve(String answer);
}
public class Jack implements CallBack{
public Tom tom;
public Jack(Tom tom ) {
// TODO Auto-generated constructor stub
this.tom=tom;
}
@Override
public void solve(String answer) {
// TODO Auto-generated method stub
System.out.println(answer);
}
public void jackAsk(String quest) {
tom.computeQuest(Jack.this, quest);
}
}
public class Mary implements CallBack {
public Tom tom;
public Mary(Tom tom) {
// TODO Auto-generated constructor stub
this.tom=tom;
}
@Override
public void solve(String answer) {
// TODO Auto-generated method stub
System.out.println(answer);
}
public void maryAsk(String string) {
// TODO Auto-generated method stub
System.out.println("maryAsk:"+string);
tom.computeQuest(Mary.this, string);
}
}
public class Tom implements CallBack {
@Override
public void solve(String answer) {
// TODO Auto-generated method stub
}
public void computeQuest(CallBack call,String quest){
System.out.println("Tom computeQuest : "+quest);
call.solve("daan");
}
}
public class Test {
public static void main(String[] args) {
//Tom 问Mary问题
// Mary mary=new Mary();
// Tom tom=new Tom(mary);
// tom.tomAsk(tom,"Tom' questiuon");
//
// Mary向Tom問題
Tom tom=new Tom();
// Mary mary=new Mary(tom);
// mary.maryAsk("瑪麗的問題");
Jack jack=new Jack(tom);
jack.jackAsk("jack's questin ?");
}
}
五:简单解释一下使用接口的好处:
如果不适用CallBack接口的话写成具体对象类型,很难完成扩展,比如张三向李四提问题,在李四计算问题方法参数中写成(Zhangsan zh,String question)样子,则李四只能给张三解决问题,如果王五也需要李四解决问题的话还得重新写一个为王五解决问题的方法,拓展性太差,但是如果使用接口的话,每一个人只需要完成实现接口都可以向李四问问题了。
六:回调方法调用时刻:
回调方法一般在李四解决完毕问题之后调用,因为只有李四计算出答案之后才能告诉张三答案,所以这个回调函数调用的时刻。
在张三提问题方法中把自己的当前实例传给李四的解决问题方法的CallBac参数中k即可。不需要在张三调用askQuest()的时候就把自己的实例传给askQuest,这样代码臃肿。