内部类的闭包与回调
来源:互联网 发布:宇宙数控系统编程 编辑:程序博客网 时间:2024/06/05 10:36
Java并不能显式地支持闭包,但对于非静态内部类而言,它不仅记录了其外部类的详细信息,还保留了一个创建非静态内部类对象的引用,并且可以直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。
通过这种仿闭包的非静态内部类,可以很方便地实现回调功能,回调就是某个方法一旦获得了内部类对象的引用后,就可以在合适时候反过来调用外部类的方法。所谓回调,就是允许客户类通过内部类引用来调用其外部类的方法,这是一种非常灵活的功能。
interface Incrementable{ void increment();}class Callee1 implements Incrementable// 实现类Callee1{ private int i = 0; @Override public void increment() { i++; System.out.println("Callee1 increment()被调用" + i + "次"); }}class MyIncrement{ public void increment() { System.out.println("MyIncrement increment()被调用饿啦"); } static void f(MyIncrement mi) { mi.increment(); }}class Callee2 extends MyIncrement// 重新定义的子类{ private int i = 0; public void increment() { super.increment(); i++; System.out.println("Callee2 increment()被调用" + i + "次"); } private class Closure implements Incrementable// 内部类实现类Closure { @Override public void increment() { Callee2.this.increment(); } } Incrementable getCallbackReference()// 返回接口引用 { return new Closure(); }}/** * @author linlin 回调类与回调方法 */class Caller{ private Incrementable callbackReference; public Caller(Incrementable callbackReference) { this.callbackReference = callbackReference; } void go() { this.callbackReference.increment(); }}public class CallBacks{ public static void main(String[] args) { Callee1 callee1 = new Callee1(); Caller caller1 = new Caller(callee1); caller1.go(); caller1.go(); Callee2 callee2 = new Callee2(); MyIncrement.f(callee2); Caller caller2 = new Caller(callee2.getCallbackReference()); caller2.go(); caller2.go(); }}输出结果如下:
Callee1 increment()被调用1次
Callee1 increment()被调用2次
MyIncrement increment()被调用饿啦
Callee2 increment()被调用1次
MyIncrement increment()被调用饿啦
Callee2 increment()被调用2次
MyIncrement increment()被调用饿啦
Callee2 increment()被调用3次
这个例子展示了外围类实现一个接口与内部类实现接口的区别。就代码而言,Callee1是简单的解决方式。Callee2继承自MyIncrement,后者已经有了一个不同的increment()方法,并且与Incrementable接口期望的increment()方法完全不相关。所以如果Callee2继承了MyIncrement,就不能为了Incrementable的用途而覆盖Increment()方法,于是只能使用内部类独立地实现Incrementable。还要注意,当创建一个内部类时,并没有在外围类的接口中添加东西,也没有修改外围类的接口。
注意,在Callee2中除了getCallbackReference()以外,其他成员都是private的。要想建立与外部世界的任何连接,interface Incrementable都是必须的。在这里可以看到,interface是如何允许接口与接口的实现完全独立地。
内部类Closure实现了Incrementable,以提供一个返回Callee2的"钩子"(hook)--而且是一个安全的钩子。无论谁获得此Incrementale的引用,都只能调用increment(),除此之外没有其他功能(不像指针那样,允许你做很多事情)。
Caller的构造器需要一个Incrementable的引用作为参数(虽然可以在任意时刻捕获回调引用),然后在以后的某个时刻,Caller对象可以使用此引用回调Callee类。
- 内部类,闭包与回调
- 内部类的闭包与回调
- 内部类_为什么需要内部类 1.闭包与回调(笔记)
- 内部类(闭包与回调)
- 内部类(闭包与回调)
- Java学习:内部类,闭包与回调
- Java -- 内部类, 成员内部类,局部内部类,匿名内部类,闭包和回调, 枚举类
- 第十章 内部类 内部类的作用、闭包、内部类继承、覆盖重写内部类、局部内部类、内部类标识符
- Java内部类之闭包(closure)与回调(callback)
- 面向对象(四)—内部类,闭包与回调
- Java—内部类(二)—实现闭包与回调
- Java_使用内部类模拟闭包和回调
- 第六天内部类与异常以及包的介绍
- 黑马程序员_包的定义与内部类总结
- 内部类和闭包
- JAVA内部类&闭包
- 从Java到Groovy(5.3. 闭包与匿名的内部类的异同点)
- 内部类大展身手 ———— 内部类提供闭包,实现回调接口
- 219. Contains Duplicate II 答案
- Codeforces 455C. Civilization (树的直径+并查集)
- JS斩杀LeetCode(1):Two Sum
- swift-oc 交互记录
- TCP的定时器系列 — SYNACK定时器
- 内部类的闭包与回调
- 用ffmpeg+qt做点有趣的事(3)----- ffmpeg解码流程
- SVN Unable to connect to a repository at URL
- 用python抓取百万网易云热门评论[转载]
- 搜索-B
- TCP的定时器系列 — 保活定时器(有图有代码有真相!!!)
- c语言中的堆栈分析
- 学会在编程当中使用警报
- 使用Mapstruct来进行PO与VO之间的映射