当前位置: 首页>編程日記>正文

N个例子让你彻底理解java接口回调

N个例子让你彻底理解java接口回调

说到接口回调,对于初学者来说,理解是真的难啊,不过没有关系,看完本篇文章,你马上就能理解接口回调啦!

概念

为了便于让大家都能无痛理解到接口回调,我决定用N个白话概念来给大家讲解,总有一种解说方式适合你:

解说1:A让B去做一件耗时(不一定耗时)的操作,而且并不知道要花费多少时间,B做完了后,告诉A事情做完了,并且把结果给A。当然,B在做这件事的时候,A还可以做其他事情。

解说2:世间总有我们难以到达的地方,比如人的胃出了问题,把头伸进去检查一下,肯定是不方便的,所以要用胃镜检查一下,就是下图这个玩意儿:
这里写图片描述
(妈妈,我在技术博客上居然看到了胃镜!)
然后我们直接将这个玩意儿伸进胃里,我估计病人就要开骂了,“你特么直接伸根管子进来要干嘛!“,确实,直接伸根管子进来,我想医生也不会做这种蠢事,然后医生会把这跟管子连接到一个特殊的仪器上,再伸管子进来,不然医生怎么看病人胃里啥情况,是吧?
如图仪器:
这里写图片描述
这个例子,我们再分析一下。管子伸进病人胃里,管子得到图像,并且将图像返回到仪器上。老实说管子和仪器其实在接口回调的思维方向中,应该是一体的,接口就是那根管子,提供提供一个得到图像的方法,仪器就是这个接口的具体实现,将接口得到的图像,显示到仪器上,医生就可以直接通过仪器看到图像了。

现在我们将这个例子,强行套上解说1中的A和B:仪器A让管子B去得到图像,仪器A也不知道管子B什么时候可以得到图像,当管子B得到图像后,马上返回给仪器A。当然,管子B在得到图像的过程中,仪器A还可以做其他事情,比如屏幕角落显示个时间啥的。

解说3: 假设我们有一根水管,通水后,一直在流水,如图:

算了,还是动图好看:

假设这是一个水管的截面图,水缓慢的从水管中流过,然后这个水管中有一些其他东西,就叫东西A吧,然后现在的水管是这个样子的:

接下来,大家打算把这个东西A给拿出来,于是制作了一个专门能抓取A的抓取器B,在水管中间掏了一个孔,然后把B放了进来,先总结下:A是东西,B是抓取器,然后现在就是这样的
其中红色是B:

然后现在东西A也被抓到了,那么就可以使用A了,由于B是一个抓取器,很多设备都可以和B直接连接,然后得到A,所以:

仪器1

仪器2

所以有很多仪器都能够连接到B,至于这些仪器拿到A干嘛,这就看每个仪器内部是怎么处理的了。

故事讲完了,接下来我要强行套用接口回调的事情了,首先在这个故事里面,我们出现了一个4种东西:

  1. 水中的A
  2. 专门获取A的B
  3. 可以和B连接的各种仪器

先说说接口回调的概念,白话文版本:接口回调就是,我们需要一个东西,而这个东西我们的仪器不能直接拿到,于是我们决定制作一个小器具深入其中,然后让那个小器具去得到我们需要的东西,这个小器具可以直接连接到我们的仪器,然后通过这个小器具把东西传给仪器。

我再把这句话稍微的加些专业词汇:接口回调就是,我们需要某些数据,但这些数据不能直接拿到,于是我们创建一个接口去帮我们拿,但接口毕竟是个接口,他啥也不能干,只能得到数据,所以我们需要这个接口的具体实现类,也就是上面白话文中的仪器。然后具体的实现类再来对数据进行处理。

大家看到上面这个概念,可能会有以下疑问:

  1. 啥数据啊,我还不能直接拿到?
  2. 为啥接口就可以拿到这些数据
  3. 啥叫接口啥也不能干啊,不能干为什么我们要用接口

问题1: 啥数据啊,我还不能直接拿到?
比如,我们写了如下代码,执行了一个data方法,是不是感觉这个data()方法毫无意义,假设这是平时开发中的某一个方法。

public class Main {public static void main(String[] args) {data();}private static void data() {int a = 100;int b = 200;int c = 300;int d = 400;}}

现在有一个data方法,我们想得到data方法里面的 变量b 的数据,
(先别吐槽这些代码很蠢,在开发中经常会遇到这些情况的,要得到某个地方的数据,直接拿又不方便,那个地方的数据多如牛毛,而我只取某些数据。)

问题2: 为啥接口就可以拿到这些数据
看着啊,接口怎么拿到这些数据的。

public class Main {// 接口interface Callback {void getData(int x);}static Callback callback;public static void main(String[] args) {data();}private static void data() {int a = 100;int b = 200;if (callback != null) {callback.getData(b);}int c = 300;int d = 400;}}

别跳,老老实实看代码,不难理解的。

看完之后一脸懵逼,大哥,这个接口有啥用,写在这里毫无意义啊。
我说你先别急,这时候抛出第三个问题:
问题3. 啥叫接口啥也不能干啊,不能干为什么我们要用接口
看到上面的代码,发现接口并没有任何卵用,为什么没卵用,因为这个接口啥也不是啊,就真的是个接口,没有被实现吧,没有被实现,怎么可能有用,那我们来实现下。

callback = new Callback() {@Overridepublic void getData(int x) {System.out.println(x);}};

匿名类实现方式,嗯,讲究,这个时候整个代码的感觉就是这样的。

public class Main {// 接口interface Callback {void getData(int x);}static Callback callback;public static void main(String[] args) {callback = new Callback() {@Overridepublic void getData(int x) {System.out.println(x);}};data();}private static void data() {int a = 100;int b = 200;if (callback != null) {callback.getData(b);}int c = 300;int d = 400;}}

这个时候,运行打印出来的数据就是200了,我们完成了接口回调。

其中之一的小用途

假设有一个耗时的操作:在网上下载一张图片,我们并不知道下载这张图片具体要花费多少时间,于是我们开一个线程去下载图片,当该线程下载完图片后,把图片给需要的人。

用法

既然是接口回调,那就少不了接口啦:

public interface CallBack {void callBack(String picture);
}

这里我们定义了一个接口,并且设置了一个方法,方法里的参数就是B执行完后返回给A的结果。

那么这个接口该怎么用呢?

这里我们假设一个场景:A需要在网上下载一张图片,但是A并不知道下载这张图片需要多少时间,于是A开了一个线程B去下载这张图片,并且B下载完后将图片给A。

这个B线程我们应该怎么写?

public class MyThread extends Thread{private CallBack callBack;public MyThread(CallBack callBack) {this.callBack = callBack;}@Overridepublic void run() {super.run();// 模仿耗时操作for (int i = 0; i < 10; i++) {try {Thread.sleep(500);System.out.println("图片下载中。。。(假装耗时)");} catch (InterruptedException e) {e.printStackTrace();}}callBack.callBack("得的图片!!!");}}

接下来我来解释下怎么理解这个线程中的接口。
我们在线程中声明了一个接口,主要是为了在耗时操作完成后,使用这个接口中的那个callBack(String picture)方法。将结果丢到这个方法的参数中。

但是卧槽!这不就是一个接口吗,方法体在哪里,就算把结果传给了这个方法里面又有什么卵用??
我的结果呢?哪去了!!!

带着这些疑问,我们开始使用这个构造方法含有接口的线程。

使用:

	MyThread myThread = new MyThread(new CallBack() {@Overridepublic void callBack(String picture) {System.out.println(picture);}});myThread.start();

我们发现在使用这个线程的时候,需要在构造方法中传递一个已经实现了该接口的类,匿名类走起。
然后会在这个匿名类中生成一个方法,原来方法体在这里,我们发现这个方法还有可以利用的参数,没错!这个参数就是经过耗时操作返回给我们的结果,也就是那张图片!!
赶快运行一波!!!

运行结果:

图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
图片下载中。。。(假装耗时)
得的图片!!!

这么简单易懂的代码真是骚的飞起!

这就是我对接口回调的理解及使用方法,希望你们看了这篇后再也不会为接口回调而烦恼!

源码下载:http://download.csdn.net/detail/it_xf/9790588


https://www.fengoutiyan.com/post/13786.html

相关文章:

  • java回调是什么意思
  • 为什么就java回调会出问题
  • java里面的回调
  • java小程序例子
  • JAVA回调函数
  • java枚举实现回调
  • java程序实例
  • java多线程回调
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機