早有写贴的打算,无奈,刚刚出来工作,也是初到北京!生活还不安定,根本没有办法来写,终于回学校了!
废话少说,在北京时,一位刚毕业的师兄,有一天问我:什么是CALLBACK!,说是面试时,有好多个公司都问了这个问题!当时我一时无语,只记着,在阅读thinking in java是看到过有关他的介绍,但具体也说不清楚了,于是赶紧翻书,上网查资料。发现虽然都说的比较全面,但是都不是好理解!后来我又阅读了c++中回调函数的概念,才对他有了一个模糊的认识!
其实我们从字面意思来判断,就已经知道他大概的意思了,我从网上摘抄的定义是:软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口(有待商榷);异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。是不是有点抽象,其实我们可以举个简单的例子:我写个程序(也可能是个类,或者是个组件)称为a,其中预留有回调函数接口,并封装好了该程序。另外一个人B要让a调用自己的程序b中的一个方法,于是,他通过我提供的接口回调自己b中的方法,目的达到。
然后我们就可以写程序了,
Code
public class Caller {
public MyCallInterface mc;
public void setCallfuc(MyCallInterface mc) {
this.mc= mc;
}
public void call(){this.mc.method();
}
}
// 我还需要定义一个接口,以便程序员B根据我的定义编写程序实现接口
public interface MyCallInterface {
public void method();
}
//于是,程序员B只需要实现这个接口就能达到回调的目的了
public class B implements MyCallInterface {
public void method() {
System.out.println("回调实现");
}
public static void main(String args[]){
Caller call = new Caller();
call.setCallfuc(new B());
call.call();}
}
OK,可以看到b实现了a回调他的方法!我们再来看个具体的例子,可能要复杂一点!有这样的一个问题:
老板(Boss)让工人(Worker)干完活告诉他干的情况如何。(来自网上的例子http://lavasoft.blog.51cto.com/62575/90453)
这是一个典型的回调问题,即工人要调用老板提供的接口,并且要老板调用学生的方法或属性,来了解工人的完成情况
代码如下:
Code
public interface Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent();
}
public class EventA implements Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventA!";
}
}
public class EventB implements Event{
/**
* 返回发生事件信息
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventB!";
}
}
public class Worker {
private Event event; //事件
private String name; //工人姓名
private Boss boss; //工人所属的老板
public Worker(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
/**
* 干活
*/
public void doWork() {
System.out.println(name + " is doing working");
//工人挺辛苦,干着枯燥乏味的重复工作,哈哈
for (int i = 0; i < 2000000; i++) {
int x = i / 234 + 234;
}
System.out.println(name + " was finished work.");
//向老板说明发生的情况
boss.getWorkerEvent(this, event);
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Boss {
private String name;
public Boss(String name) {
this.name = name;
}
/**
* 老板接收工人的事件
* @param worker 工人
* @param event 事件
*/
public void getWorkerEvent(Worker worker, Event event) {
System.out.println("老板接收到事件信息: "+worker.getName() + ": " + event.happendEvent());
}
}
public class Test {
public static void main(String args[]){
//初始化老板和工人
Boss boss = new Boss("老板");
Worker worker1= new Worker("张三",boss);
Worker worker2= new Worker("李四",boss);
//捏造两个事件
Event event1 = new EventA();
Event event2 = new EventB();
//事件是工人发出的
worker1.setEvent(event1);
worker2.setEvent(event2);
//工人干活,干完了通知老板干的情况如何
worker1.doWork();
worker2.doWork();
}
}
我们可以看到在boss中,我们回调了工人的happendEvent方法,一般我们都用接口来实现回调!