接口回调,用最简单的一个匿名内部类来讲解(附接口回调高级应用场景,让你对接口的了解登堂入室)
2018-01-05 16:59
435 查看
接口回调,是Java开发者必须要学的一个东西,可是他呢,书上没有,大神博客里也没有,所以导致了有部分小伙纸并不了解这个知识,所以这里做一个最简单的讲解。
(先不牵扯什么异步回调、同步回调)
首先,只需要记住一点,接口回调的含义就是把代码换个地方写。
正常我们是这样写的
可是我们因为某种原因,不得不把代码放到另外一个地方去写,怎么办?我们第一时间想到的是,再新建一个方法,调用这个方法即可。
这样其实已经算是回调了,但是我们没有采用接口,采用的是方法,所以称之为方法回调。
但是因为种种原因(原因稍后会讲),我们不能总写在我们这一个类里吧?所以我们需要弄一个类,这里用内部类的形式
但是总是要新建一个类,这性能开销和代码量开销也太大了吧!所以我们采用接口的形式
定义一个内部接口,再“实例化”这个接口,再调用这个接口里的方法。这就是接口回调了。
有人可能有疑问,为什么接口可以实例化呢?其实上述代码,是创建了一个匿名内部类,再继承了这个接口,效果等同于下面的代码:
创建一个类,继承这个接口,调用的是这个类的方法。而上面的就是通过匿名内部类的形式,其实就是Java的语法糖,让你可以少些许多代码。讲到这里,看官肯定已经对接口回调掌握通透了。
下面来分析下,为什么需要用接口回调,接口回调的应用场景是怎么样的。
onClick就是一例
当你的点击事件点击了,他不会立刻执行代码,他会执行onClick方法,而onClick方法是交给我们来实现的。所以我们可以验证我们的结论,接口回调就是让你的代码换一个地方执行。如果你没有设置这个监听器的话,那么虽然有点击事件,但是方法肯定得不到执行。但是如果设置了监听器的话,你所设置的接口里的方法就会得到执行。所以我们想进行接口回调,就必须让调用者得到你这个接口。很显然这个setOnClickListener就是一个传递接口的方法。
可以看一下源码
看,这里就是把我们传进来的接口赋值了。可想而知,最后我们执行的时候,肯定会调用getListenerInfo().mOnClickListener.onClick,感兴趣的同学可以自行查看源码。我们说了我们想进行接口回调,就必须让调用者得到你这个接口,我们之前为什么没有设置接口的方法呢?因为接口就是一个成员变量啊,自然可以直接调用。而如果你平时在用的时候,发现想要让两个类之间进行通信,那么你必须先获取其中的那个类的实例,比如说是object,再调用objet.setListener(listener)即可。
其实这种简单的应用还有很多很多,下面介绍一下进阶的应用。Android消息机制。
安卓的消息机制和接口回调有啥区别呢?其实消息机制的基础就是接口回调!只不过,他把你所有的接口都进入一个队列,可以灵活自如地控制这一系列的回调何时执行,先后顺序。上图:
图中的每个小方块,都是一个接口。这里就是消息的灵活性了。此外他可以灵活地切换线程,实现线程间的通信,这也是普通的接口回调做不到的。
看似神秘的观察者模式
何为观察者模式,他和接口回调的区别简单来说就是他是一对多的。比如有多个观察者同时观察着一个被观察者,在被观察者改变的时候,观察者全部都观察到了,并且做出了响应。这个过程看似高大上,其实无非也不过是利用了接口回调。 已经精通接口回调的你应该可以轻松想到是怎么实现的了。他就是当被观察者内容改变时,会执行被观察 者中的某个方法,而该方法里面调用的是所有观察者接口中的方法,从而实现了一对多的观察。
再上升一下,架构,MVP模式
MVP分V层,P层,M层。通俗来讲,V是UI,P是媒婆,M是业务。P中会维护V层和M层的引用,通过分别调用V层和M层的接口中的方法,来实现业务和UI的分离。
(先不牵扯什么异步回调、同步回调)
首先,只需要记住一点,接口回调的含义就是把代码换个地方写。
正常我们是这样写的
public class Data3 extends MyData { Data3() { System.out.print("-----"); }
可是我们因为某种原因,不得不把代码放到另外一个地方去写,怎么办?我们第一时间想到的是,再新建一个方法,调用这个方法即可。
public class Data3 extends MyData { Data3() { cal(); } void cal() { System.out.print("-----"); }
这样其实已经算是回调了,但是我们没有采用接口,采用的是方法,所以称之为方法回调。
但是因为种种原因(原因稍后会讲),我们不能总写在我们这一个类里吧?所以我们需要弄一个类,这里用内部类的形式
public class Data3 extends MyData { Data3() { C c = new C(); c.cal(); } class C { void cal() { System.out.print("-----"); } }
但是总是要新建一个类,这性能开销和代码量开销也太大了吧!所以我们采用接口的形式
public class Data3 extends MyData { Data3() { call.whatToDo(); } Call call = new Call() { @Override public void whatToDo() { System.out.print("-----"); } }; interface Call { void whatToDo(); } }
定义一个内部接口,再“实例化”这个接口,再调用这个接口里的方法。这就是接口回调了。
有人可能有疑问,为什么接口可以实例化呢?其实上述代码,是创建了一个匿名内部类,再继承了这个接口,效果等同于下面的代码:
public class Data3 extends MyData { Data3() { xxx x = new xxx(); x.whatToDo(); } interface Call { void whatToDo(); } class xxx implements Call { @Override public void whatToDo() { System.out.print("-----"); } } }
创建一个类,继承这个接口,调用的是这个类的方法。而上面的就是通过匿名内部类的形式,其实就是Java的语法糖,让你可以少些许多代码。讲到这里,看官肯定已经对接口回调掌握通透了。
下面来分析下,为什么需要用接口回调,接口回调的应用场景是怎么样的。
onClick就是一例
mRv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //do some thing } });
当你的点击事件点击了,他不会立刻执行代码,他会执行onClick方法,而onClick方法是交给我们来实现的。所以我们可以验证我们的结论,接口回调就是让你的代码换一个地方执行。如果你没有设置这个监听器的话,那么虽然有点击事件,但是方法肯定得不到执行。但是如果设置了监听器的话,你所设置的接口里的方法就会得到执行。所以我们想进行接口回调,就必须让调用者得到你这个接口。很显然这个setOnClickListener就是一个传递接口的方法。
可以看一下源码
public void setOnClickListener(@Nullable OnClickListener l) { if (!isClickable()) { setClickable(true); } getListenerInfo().mOnClickListener = l; }
看,这里就是把我们传进来的接口赋值了。可想而知,最后我们执行的时候,肯定会调用getListenerInfo().mOnClickListener.onClick,感兴趣的同学可以自行查看源码。我们说了我们想进行接口回调,就必须让调用者得到你这个接口,我们之前为什么没有设置接口的方法呢?因为接口就是一个成员变量啊,自然可以直接调用。而如果你平时在用的时候,发现想要让两个类之间进行通信,那么你必须先获取其中的那个类的实例,比如说是object,再调用objet.setListener(listener)即可。
其实这种简单的应用还有很多很多,下面介绍一下进阶的应用。Android消息机制。
安卓的消息机制和接口回调有啥区别呢?其实消息机制的基础就是接口回调!只不过,他把你所有的接口都进入一个队列,可以灵活自如地控制这一系列的回调何时执行,先后顺序。上图:
图中的每个小方块,都是一个接口。这里就是消息的灵活性了。此外他可以灵活地切换线程,实现线程间的通信,这也是普通的接口回调做不到的。
看似神秘的观察者模式
何为观察者模式,他和接口回调的区别简单来说就是他是一对多的。比如有多个观察者同时观察着一个被观察者,在被观察者改变的时候,观察者全部都观察到了,并且做出了响应。这个过程看似高大上,其实无非也不过是利用了接口回调。 已经精通接口回调的你应该可以轻松想到是怎么实现的了。他就是当被观察者内容改变时,会执行被观察 者中的某个方法,而该方法里面调用的是所有观察者接口中的方法,从而实现了一对多的观察。
再上升一下,架构,MVP模式
MVP分V层,P层,M层。通俗来讲,V是UI,P是媒婆,M是业务。P中会维护V层和M层的引用,通过分别调用V层和M层的接口中的方法,来实现业务和UI的分离。
相关文章推荐
- 弱引用和软引用WeakReference,SoftReference,最简讲解,以及一个应用场景
- Thinking in java 读书笔记(七.1:内部类:匿名内部类和内部类的简单应用)
- 《Java编程思想》之更好了解内部类的价值(一个简单的例子)
- ios学习笔记block回调的应用(一个简单的例子)
- java 匿名内部类和接口回调的相似之处
- 《Java编程思想》之更好了解内部类的价值(一个简单的例子)
- 《Java编程思想》之更好了解内部类的价值(一个简单的例子)
- 一个简单的仿Button设定监听接口,以及回调方法
- 牛客网Java刷题知识点之匿名对象、匿名对象的内存结构图、匿名对象的应用场景、匿名对象的使用、匿名对象的简单例子、匿名对象要注意的事项
- 匿名内部类是否可以继承其它类?是否可以实现接口? 代码讲解
- Java实现匿名内部类的简单应用
- php接口技术实现一个简单的多态应用实例
- 使用内部类写的一个简单回调
- iOS开发UI高级—10使用picker View控件完成一个简单的选餐应用
- 创建一个简单的接口回调
- 自定义接口内部类的一个简单的使用(跨类传值)
- ios学习笔记block回调的应用(一个简单的例子)
- 参考Spring模板模式和回调接口的一个应用
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- c#接口简单易懂的一个例子