【原】回调机制
一直对回调机制不明白?回调?什么鬼?干嘛使的?有毛用?
其实顾名思义,回调就是“回过头来调用对方”。即:当我联系你时,你又回过头来联系我。对,没错,就是好莱坞法则——“Don't call me; I'll call you.”
不过这里需要改一点细节,“don't bother me, if you are really good ,I'll call you ,but firstly,you should tell me your number”
这样解释是不是有点小明白了?不明白?没关系,继续往下来
网上关于回调机制的博文太多了,大家肯定知道,回调是【“A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D”】blahblah
如果把A当做是演员的话,B当做好莱坞,那么首先演员A给好莱坞B打了一个电话,然后好莱坞B又反过来联系演员A。
but!第一次调用A CALL B,其实是为了让B call A啊。还是不明白?
情景融入型:
-----------------------------------------以下是背景----------------------------------------------
好莱坞很牛,演员都很想进,but,hollywood的管理非常规范,有自己的一套标准【瞅清楚了,这个标准是B制定的,对B是可知的】,所有想进来的演员必须服从这套标准(接口)【A类必须服从这套标准】
interface ActorStandard{
void 培养();
.....
}
---------------------------------以下是第一次调用---------------------------------------
A:“喂?是好莱坞吗?我是演员A,我现在给你打电话,这个就是我的手机号,我很牛哦,而且符合你们的标准哦”(实现接口ActorStandard)
B:“好的,我记下你的电话了,我一会儿看看你的作品,真的牛逼的话,我就联系你的”
---------------------------------以下是第二次调用----------------------------------------
B:“是A吗?你的确很牛,我们接受你了。接下来,我们会包装你(调用A中的接口方法实现),推广你(调用A中的接口方法实现)。。。”
--------------------------------回调完毕-----------------------------------------
明白了吗?第一次A调用B其实恰恰是为了让B调用A(中的方法),
那么问题来了:
第一次调用的意义在哪儿?
答:因为B只定义了规范,并不知道A的存在!第一次调用使得B知道了A的存在,因此这次调用主要是注册登记A的信息。所以第一次调用的函数也可以称作注册函数。
如果不采用回调,用直接调用可以吗?
答:这种情况是不可以的,首先我们看一下这三个类/接口的关系。
B制定的标准ActorStandard,因此目前为止,ActorStandard对B是可见的,但是演员A对B是不可见的。
于是,B类如想与ActorStandard有交互,则其中必须要包含一个ActorStandard,但是由于ActorStandard只是接口,因此,其实现类只能从外面传进来。
演员A要符合ActorStandard标准,因此ActorStandard对A是可见的。而且演员A要先去B那里注册,所以B对A也是可见的。
于是,A类要实现ActorStandard的接口,其次A类中要有B类的对象,以便在B那里注册登记自己的信息。
为啥A一定要去B那里注册?
答:上面说了,B只认识ActorStandard这个接口,如果A这个实现类对B一直保持透明,那两者之间如何做交互?
因此,结构应该是这样的。
1 package test; 2 3 interface ActorStandard{ 4 void bringUp(); 5 String getName(); 6 } 7 8 class Actor implements ActorStandard{ 9 private Hollywood hollywood; 10 private String name; 11 //这个方法虽然在Actor类中,但是往往是提供给Hollywood调用的,自己不调用 12 //为什么? 13 //因为Actor只是实现了标准啊,这个标准的制定者是Hollywood。动作的执行者也是Hollywood。 14 //自己的方法,让别人调用,而且是自己的调用者反过来调用自己的方法,因此叫回调【不知道能不能理解】 15 public void bringUp(){ 16 System.out.println("准备培养...."); 17 System.out.println("先包装一下..."); 18 System.out.println("再炒作一番..."); 19 } 20 public String getName() { 21 return name; 22 } 23 public Actor(Hollywood hollywood, String name) { 24 this.hollywood = hollywood; 25 this.name = name; 26 } 27 public void call(){//第一次调用,完成注册 28 System.out.println("I am " + name + ", I am gona call hollywood"); 29 hollywood.register(this); 30 } 31 } 32 33 class Hollywood { 34 public void register(ActorStandard actor){//注册完成 35 System.out.println("this is hollywood,I received a phone"); 36 System.out.println("oh, now I know this call is from " + actor.getName()); 37 System.out.println("he is purly good,I am gonna to bring up with him"); 38 actor.bringUp();//第二次调用,反向调用。所谓callback 39 } 40 } 41 42 public class CallBackTest { 43 public static void main(String[] args) { 44 Hollywood hollywood = new Hollywood(); 45 Actor hughJackman = new Actor(hollywood, "Hugh Jackman"); 46 hughJackman.call(); 47 } 48 }
运行结果如下:
I am Hugh Jackman, I am gona call hollywood
this is hollywood,I received a phone
oh, now I know this call is from Hugh Jackman
he is purly good,I am gonna to bring up with him
准备培养....
先包装一下...
再炒作一番...
如果还不明白,那我是真的没办法了。我在网上找了很多文章,但是基本上都没有解释接口和B类之间的关系,所以看下来还是云里雾里的,至于回调有什么用?可以结合异步来看,请看这篇博文,还有这篇,还有这篇。这篇我还没看,应该也不错。
本文纯粹是今晚突然搞懂,想趁热打铁记录一下,肯定存在理解偏差,逻辑硬伤等问题。以后抽空完善一下。
如果各位看完还不懂,抱歉浪费大家的时间了,可以留言讨论。