激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - Java 是如何利用接口避免函數(shù)回調(diào)的方法

Java 是如何利用接口避免函數(shù)回調(diào)的方法

2021-04-05 13:20Wray Zheng JAVA教程

本篇文章主要介紹了Java 是如何利用接口避免函數(shù)回調(diào)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、引言

在許多編程語言中,都有函數(shù)回調(diào)這一概念。C 和 C++ 中有函數(shù)指針,因此可以將函數(shù)作為參數(shù)傳給其它函數(shù),以便過后調(diào)用。而在 JavaScript 中,更是將函數(shù)回調(diào)發(fā)揮到了極致,各種事件的處理,特別是異步事件,基本都靠函數(shù)回調(diào)來完成。

在 Java 中,同樣可以實(shí)現(xiàn)函數(shù)回調(diào)。雖然沒有函數(shù)指針,但 Java 可以通過反射機(jī)制來獲得一個(gè)類的方法,將其以 java.lang.reflect.Method 類型參數(shù)傳遞給其它函數(shù),然后通過 Method 對(duì)象的 invoke 方法來調(diào)用該函數(shù)。

盡管如此,這種方式的調(diào)用步驟相對(duì)繁瑣、執(zhí)行效率低、難以調(diào)試。在 Java 中,有比函數(shù)回調(diào)更加優(yōu)雅的機(jī)制,那就是接口

二、為什么需要函數(shù)回調(diào)

函數(shù)回調(diào),實(shí)際上是延遲實(shí)現(xiàn)某些功能的一種方式。

如果我們事先知道程序應(yīng)該執(zhí)行哪些操作,那么完全不需要函數(shù)回調(diào),直接在編程時(shí)實(shí)現(xiàn)即可。

但很多時(shí)候,在編寫代碼時(shí),特別是寫工具類、功能庫或框架時(shí),實(shí)現(xiàn)的是相對(duì)通用和抽象的功能,而具體場(chǎng)景下的功能則由使用這些類的開發(fā)者來實(shí)現(xiàn)。

函數(shù)回調(diào),可以解決這種事先不知道具體實(shí)現(xiàn)的情況。

排序函數(shù)的例子

舉例來說,當(dāng)我們要實(shí)現(xiàn)一個(gè)通用的排序函數(shù)時(shí),事先并不知道其他開發(fā)者會(huì)用該函數(shù)來對(duì)哪些類型的元素進(jìn)行排序,也就不知道以何種標(biāo)準(zhǔn)來判斷這些元素的偏序(大小)關(guān)系。

因此,可以要求其他開發(fā)者在使用排序函數(shù)時(shí),必須提供一個(gè)比較函數(shù) compare,這樣我們就可以用 compare 比較待排序元素的大小,而無需事先知道元素是什么類型,也無需知道 compare 的具體實(shí)現(xiàn)。

這里 compare 函數(shù)對(duì)于排序函數(shù)來說,就是回調(diào)函數(shù)。

偽代碼表示如下:

?
1
2
3
4
5
6
7
8
9
10
//通用的排序函數(shù)
void sort(Object[] array, Method compare) {
  //利用 compare 函數(shù)比較 array 中元素的大小關(guān)系
  //以便對(duì) array 進(jìn)行排序
}
 
//由調(diào)用者實(shí)現(xiàn)具體的比較函數(shù)
int compare(Object a, Object b) {
  //比較元素a、b,并返回大小關(guān)系
}

異步處理函數(shù)的例子

再比如說,當(dāng)我們編寫一個(gè)異步處理函數(shù)時(shí),事先不知道其他開發(fā)者在處理完成時(shí)要進(jìn)行哪些操作,因?yàn)檫@些操作只有在特定場(chǎng)景下使用該函數(shù)時(shí)才能知道。

于是可以要求開發(fā)者在使用該函數(shù)時(shí),提供一個(gè)回調(diào)函數(shù) callback。這樣我們?cè)诰帉懏惒教幚砗瘮?shù)時(shí),就可以調(diào)用 callback 函數(shù)來進(jìn)行一些收尾的工作,而無需事先知道這些收尾的工作是什么。

偽代碼表示如下:

?
1
2
3
4
5
6
7
8
9
10
//異步處理函數(shù)
void asynProcess(Method callback) {
  //執(zhí)行異步任務(wù)
  callback();
}
 
//由調(diào)用者實(shí)現(xiàn)具體的回調(diào)函數(shù)
void callback() {
  //異步處理完成后要進(jìn)行的操作
}

三、用接口代替函數(shù)回調(diào)

上面我們提到,之所以使用函數(shù)回調(diào)這一方式,是因?yàn)?事先不知道某些功能的具體實(shí)現(xiàn),因此將具體實(shí)現(xiàn)留給其他開發(fā)者完成。

有沒有覺得這句話仿佛在描述 Java 的接口?接口(interface)是一組方法的抽象定義,具體實(shí)現(xiàn)由實(shí)現(xiàn)該接口的類來完成。

所以,利用面向?qū)ο蠛徒涌谶@兩個(gè)特性,可以代替函數(shù)回調(diào)。

我們以上面舉的兩個(gè)例子來說明接口是如何代替函數(shù)回調(diào)的。

排序函數(shù)

用接口實(shí)現(xiàn)排序函數(shù),不再要求開發(fā)者在使用該排序函數(shù)時(shí)提供回調(diào)函數(shù) compare,而是要求開發(fā)者確保待排序元素實(shí)現(xiàn)了 Comparable 接口,基于“待排序元素已經(jīng)實(shí)現(xiàn)了 Comparable 接口“這一前提下,我們無需知道待排序元素的類型,就可以實(shí)現(xiàn)排序功能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//通用的排序函數(shù)
void sort(Object[] array) {
  //利用 Comparable 接口的 compareTo 方法
  //比較元素的大小,以便對(duì) array 進(jìn)行排序。
}
 
//由排序函數(shù)定義的接口
public interface Comparable {
  public int compareTo(Object other);
}
 
//由調(diào)用者實(shí)現(xiàn) Comparable 接口
public class Element implements Comparable {
  @Override
  public int compareTo(Object other) {
    //判斷當(dāng)前 Element 與 other 的大小關(guān)系
    //并返回兩者的關(guān)系
  }
}

異步處理函數(shù)

使用接口來實(shí)現(xiàn)異步處理函數(shù)時(shí),不要求開發(fā)者提供回調(diào)函數(shù) callback,而是要求提供一個(gè)實(shí)現(xiàn)了指定接口的對(duì)象,這很好地體現(xiàn)了 Java 面向?qū)ο蟮乃枷搿O啾忍峁┮粋€(gè)函數(shù),一個(gè)對(duì)象包含的信息更豐富,使用起來更加靈活。但本質(zhì)上,該異步處理函數(shù)還是利用接口來完成收尾工作的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//異步處理函數(shù)
void asynProcess(ActionListener al) {
  //執(zhí)行異步任務(wù)
  al.actionPerformed();
}
 
//由異步處理函數(shù)定義的接口
public interface ActionListener {
  void actionPerformed();
}
 
//由調(diào)用者實(shí)現(xiàn) ActionListener 接口
public class ExtraTask implements ActionListener {
  @Override
  public void actionPerformed() {
    //異步處理函數(shù)執(zhí)行完成時(shí),需要進(jìn)行的額外工作
  }
}
 
//調(diào)用異步處理函數(shù)
public static void main(String[] args) {
  asynProcess(new ExtraTask());
}

四、總結(jié)

回調(diào)方式可以總結(jié)為:實(shí)現(xiàn)一個(gè)通用函數(shù) func,在具體場(chǎng)景中調(diào)用這個(gè)通用函數(shù)時(shí),調(diào)用者需要提供合適的回調(diào)函數(shù) callback。通用函數(shù) func 利用該回調(diào)函數(shù),完成具體場(chǎng)景中的任務(wù)。

而接口實(shí)現(xiàn)的方式則是:實(shí)現(xiàn)一個(gè)通用函數(shù) func,在具體場(chǎng)景中調(diào)用這個(gè)通用函數(shù)時(shí),被操作的對(duì)象需要自己實(shí)現(xiàn)合適的接口,通用函數(shù)會(huì)利用該接口,完成具體場(chǎng)景中的任務(wù)。

利用函數(shù)回調(diào)或者接口,都可以解決事先不知道具體實(shí)現(xiàn)的情況。函數(shù)回調(diào)方式傳遞的是函數(shù),而接口方式傳遞的是實(shí)現(xiàn)了該接口的對(duì)象。

在 Java 中,函數(shù)回調(diào)需要利用反射機(jī)制來完成,易出錯(cuò)、效率低,而使用接口可以讓代碼的邏輯更加清晰、運(yùn)行效率更高、也更便于調(diào)試。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.codebelief.com/article/2018/02/java-how-to-use-interface-to-avoid-function-callback

延伸 · 閱讀

精彩推薦
1276
主站蜘蛛池模板: 亚洲成人欧美 | av在线浏览 | 欧美精品电影一区二区 | 激情宗合网 | 伊人亚洲精品 | 黄色片快播 | 一本视频在线观看 | 国产在线欧美日韩 | 亚洲精品免费播放 | 中文字幕激情视频 | 一级电影免费 | 国产妇女乱码一区二区三区 | 久久国产精品久久久久久 | 久久精精品 | 激情网站免费观看 | 午夜视频在线免费播放 | 日本羞羞影院 | 91性高湖久久久久久久久网站 | 黄色大片网 | 毛片大全在线观看 | 国产精品99久久久久久久女警 | 九九热视频免费 | 久久综合精品视频 | 911精品影院在线观看 | 91精选视频 | 国产一区在线视频观看 | 黄色片网站免费 | 91精品国啪老师啪 | 二区三区在线观看 | 毛片免费观看日本中文 | 曰韩一二三区 | av免费在线观看不卡 | 亚洲福利视频52 | 999久久久久久 | 国产午夜亚洲精品 | 激情宗合网 | 欧美一级爱爱 | 精品成人免费一区二区三区 | 国产精品久久久久久久久久了 | 国产一区二区欧美 | 广州毛片 |