Water2Wine

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
1. 通俗概念

所谓回调,就是客户程序C调用服务程序S中的某个方法a,然后S的方法a又在某个时候反过来调用C中的某个方法b,对于C来说,这个b便叫做回调函数。

一般说来,C不会自己调用b,C提供b的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的b叫甚名谁,所以S会约定b的接口规范(函数原型),然后由C提前通过S的一个函数r告诉S自己将要使用b函数,这个过程称为回调函数的注册,r称为注册函数。

下面举个通俗的例子:

某天,我打电话向你请教问题,当然是个难题,😃,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。

这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。

如果你还不太清楚看看这段描述合和代码:

声明一个接口,另外一个类有方法里面有个参数以是这个接口类型的,而后在另外类中实现这个接口(java中多用的是匿名内部类),而且以这个匿名的类生成的对象为参数传到上面提到类中,而后实现回调.......这种用法可以参考java里面常用到的数据库操作所用到的几个接口.....

2. 经典的回调方式

定义CallBack接口约定函数b的原型————确定获取问题答案的函数
Class A实现接口CallBack————双方约定好问题答案的规范
Class A中包含一个Class B的引用b————我有你的手机号码
Class B中有一个参数含callback的方法f————我能打电话问你问题,你能思考问题
A的对象a调用B的方法f————你能将思考问题的结果打电话告诉我

3. 代码样例
/**
 * 这是一个回调接口
 * @author xiaanming
 *
 */
public interface CallBack {
	/**
	 * 这个是小李知道答案时要调用的函数告诉小王,也就是回调函数
	 * @param result 是答案
	 */
	public void solve(String result);
}
/**
 * 这个是小王
 * @author xiaanming
 * 实现了一个回调接口CallBack,相当于----->背景一
 */
public class Wang implements CallBack {
	/**
	 * 小李对象的引用
	 * 相当于----->背景二
	 */
	private Li li; 
 
	/**
	 * 小王的构造方法,持有小李的引用
	 * @param li
	 */
	public Wang(Li li){
		this.li = li;
	}
	
	/**
	 * 小王通过这个方法去问小李的问题
	 * @param question  就是小王要问的问题,1 + 1 = ?
	 */
	public void askQuestion(final String question){
		//这里用一个线程就是异步,
		new Thread(new Runnable() {
			@Override
			public void run() {
				/**
				 * 小王调用小李中的方法,在这里注册回调接口
				 * 这就相当于A类调用B的方法C
				 */
				li.executeMessage(Wang.this, question); 
			}
		}).start();
		
		//小网问完问题挂掉电话就去干其他的事情了,诳街去了
		play();
	}
 
	public void play(){
		System.out.println("我要逛街去了");
	}
 
	/**
	 * 小李知道答案后调用此方法告诉小王,就是所谓的小王的回调方法
	 */
	@Override
	public void solve(String result) {
		System.out.println("小李告诉小王的答案是--->" + result);
	}
	
}
/**
 * 这个就是小李啦
 * @author xiaanming
 *
 */
public class Li {
	/**
	 * 相当于B类有参数为CallBack callBack的f()---->背景三
	 * @param callBack  
	 * @param question  小王问的问题
	 */
	public void executeMessage(CallBack callBack, String question){
		System.out.println("小王问的问题--->" + question);
		
		//模拟小李办自己的事情需要很长时间
		for(int i=0; i<10000;i++){
			
		}
		
		/**
		 * 小李办完自己的事情之后想到了答案是2
		 */
		String result = "答案是2";
		
		/**
		 * 于是就打电话告诉小王,调用小王中的方法
		 * 这就相当于B类反过来调用A的方法D
		 */
		callBack.solve(result); 
 
		
		
	}
	
}
/**
 * 测试类
 * @author xiaanming
 *
 */
public class Test {
	public static void main(String[]args){
		/**
		 * new 一个小李
		 */
		Li li = new Li();
 
		/**
		 * new 一个小王
		 */
		Wang wang = new Wang(li);
		
		/**
		 * 小王问小李问题
		 */
		wang.askQuestion("1 + 1 = ?");
	}
}

测试结果:

posted on 2020-08-07 11:44  Water2Wine  阅读(126)  评论(0编辑  收藏  举报