【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类。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。