【java in think】内部类的闭包与回调
1 interface Incrementable 2 { 3 void increment(); 4 } 5 6 class Callee1 implements Incrementable// 实现类Callee1 7 { 8 private int i = 0; 9 10 @Override 11 public void increment() 12 { 13 i++; 14 System.out.println("Callee1 increment()被调用" + i + "次"); 15 } 16 17 } 18 19 class MyIncrement 20 { 21 public void increment() 22 { 23 System.out.println("MyIncrement increment()被调用饿啦"); 24 } 25 26 static void f(MyIncrement mi) 27 { 28 mi.increment(); 29 } 30 } 31 32 class Callee2 extends MyIncrement// 重新定义的子类 33 { 34 private int i = 0; 35 36 public void increment() 37 { 38 super.increment(); 39 i++; 40 System.out.println("Callee2 increment()被调用" + i + "次"); 41 } 42 43 private class Closure implements Incrementable// 内部类实现类Closure 44 { 45 46 @Override 47 public void increment() 48 { 49 Callee2.this.increment(); 50 } 51 52 } 53 54 Incrementable getCallbackReference()// 返回接口引用 55 { 56 return new Closure(); 57 } 58 } 59 60 /** 61 * @author linlin 回调类与回调方法 62 */ 63 class Caller 64 { 65 private Incrementable callbackReference; 66 67 public Caller(Incrementable callbackReference) 68 { 69 this.callbackReference = callbackReference; 70 } 71 72 void go() 73 { 74 this.callbackReference.increment(); 75 } 76 } 77 78 public class CallBacks 79 { 80 81 public static void main(String[] args) 82 { 83 Callee1 callee1 = new Callee1(); 84 Caller caller1 = new Caller(callee1); 85 caller1.go(); 86 caller1.go(); 87 88 Callee2 callee2 = new Callee2(); 89 MyIncrement.f(callee2); 90 Caller caller2 = new Caller(callee2.getCallbackReference()); 91 caller2.go(); 92 caller2.go(); 93 94 } 95 96 }
输出结果如下:
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类。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。