之前一直對回調這個概念不甚理解,對某一概念不理解但該概念又總總出現實在讓人不爽,今天總算忍無可忍,發動Google和知乎技能,總算對回調有了那么一點點感覺,而在查資料的過程中也有一些驚喜的發現。
我覺得,以下的兩個回答對理解回調很有幫助。
首先是futeng的回答,給出了一種通俗易懂的,由淺入深的,符合人類自然認知過程的解答。對于初學者來說,是一個很好的答案。futeng在其中提到
在Java社區的各種開源工具中,回調方法的使用俯拾即是。所以熟悉回調方法無疑能加速自己對開源輪子的掌握。網上搜了一些文章,奈何對回調方法的介紹大多只停留在什么是回調方法的程度上。本篇文章嘗試從回調方法怎么來的、為什么要使用回調方法以及在實際項目中如何使用等方面來介紹下。
而另一位黃兢成則給出了更一般性的回答,解釋了回調的本質
這個是程序上的概念。
本質上是叫別人做事,傳進去的額外信息。
并且提到一個自己從沒想到過的觀點——代碼和數據的統一性
再跟著,就來到計算機中比較詭異的地方。也就是代碼(code)和數據(data)的統一,這是一個檻,如果不打通這個,很多概念就不清楚。我們常常說計算機程序分成code和data兩部分。很多人就會覺得,code是會運行的,是動的,data是給code使用,是靜態的,這是兩種完全不同的東西。
其實code只是對行為的一種描述,比如有個機器人可以開燈,關燈,掃地。跟著我要機器人開燈,掃地,關燈。如果跟機器人約定好,0表示開燈,1表示關燈,2表示掃地。我發出指令,0 1 2 1 0。跟著就可以控制機器人開燈,掃地,關燈。再約定用二進制表示,兩位一個指令,就有一個數字串,0001110100,這個時候0001110100這串數字就描述了機器人的一系列動作,這個就是從一方面理解是code,可以它可以控制機器人的行為。但另一方面,它可以傳遞,可以記錄,可以修改,也就是數據。只要大家都協商好,code就可以編碼成data, 將data解釋運行的時候,也變成了code。
這個地方扯開了。我自己是不區分code和data的,統一稱為信息。那既然int max(int a, int b)中int,double等表示普通data的東西可以傳遞進去,憑什么表示code的函數就不可以傳進去了。有些語言確實是不區分的,它的function(表示code)跟int, double的地位是一樣的。這種語言就為函數是第一類值。
最后提到,如果認清了本質,什么委托,代理,監聽,觀察者之類的,其實都是一回事。
其實你理解了,根本不用去關心術語的。術語是別人要告訴你啊,或者你去告訴人啊,使用的一套約定的詞語。本質上就個東西,結果會有很多術語的。
跟著再將回調的概念進化,比如某人同時關心A,B,C,D,E,F事件,并且這些事件是一組的,比如敲鍵盤,鼠標移動,鼠標點擊等一組。將一組事件結合起來。在有些語言就變成一個接口,接口有N個函數。有些語言就映射成一個結構,里面放著N個函數指針。跟著就不是將單個函數指針傳進去,而是將接口,或者函數指針的結構傳進去。這些根據不同的用途,有些人叫它為代理啊,監聽者啊,觀察者啊等等。
具體到Java語言,經過查資料,發現有如下兩種方法
http://blog.csdn.net/eyeooo/article/details/11971145
這里有一個類Printer并且提供了一個Callback接口,當其它類委托Printer做某些事情時,要向Printer類提供某些信息,這些信息可以是Printer所要用到的數據,也可以是告訴Printer具體怎么做(這里可以看出數據和代碼統一了),具體到本例,就是一個Callback接口的具體實現。http://blog.csdn.net/xiaanming/article/details/8703708
這里方式是某一個類Wang保留一個它要委托類的引用(其實上面方式中也是主類保留了Printer類的引用),而Wang本身要實現一個Callback接口,并將Wang的引用傳遞給被委托類。該種方式與方式1的區別于,Callback接口的實現是由第三方類實現而非調用類實現,而本方式是由調用類本身實現接口。
以上是自己的一種拙見,因為平時沒有應用過,難免理解有誤,希望大家指出。
在此記下,供自己以后回顧方便。