标题是 Java编程思想 里的一小节,其总结为:内部类最吸引人的原因是每个内部类都能独立地继承自一个实现,所以无论外部类是否已经继承了某个实现,对于内部类都没有影响。内部类使得多继承更加完整。
如果不需要使用多继承,就不需要使用内部类,但如果使用内部类,就可以获得一些其他特性:
- 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外部类对象的信息相独立。
- 在单个外部类中,让多个内部类以不同的方式实现同一个接口,或继承同一个类。
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。
//一个实现递增功能的接口
interface Incrementable {
void increment();
}
//一个简单的实现类(callee意为被调用者)
class Callee1 implements Incrementable {
private int i = 0;
//Callee1对接口的实现是递增并打印
public void increment() {
i++;
System.out.println(i);
}
}
//另一个类有自己不同的increment()方法?
class MyIncrement {
public void increment() {
System.out.println("Other operation");
}
static void f(MyIncrement m) {
m.increment();
}
}
//让Callee2实现不同的increment()方法
class Callee2 extends MyIncrement {
private int i = 0;
public void increment() {
super.increment();
i += 2;
System.out.println(i);
}
//内部类Closure(闭包)是第二种对接口的实现类
private class Closure implements Incrementable {
public void increment() {
Callee2.this.increment();
}
}
//获得一个闭包的引用
Incrementable getCallbackReference() {
return new Closure();
}
}
//调用者
class Caller {
private Incrementable callbackReference;
Caller(Incrementable cbh) {
callbackReference = cbh;
}
void go() {
callbackReference.increment();
}
}
public class Test {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
Caller caller1 = new Caller(c1);
//之所以不能用c2.new Closure()是因为Closure是私有的
Caller caller2 = new Caller(c2.getCallbackReference());
caller1.go();
caller1.go();
caller2.go();
}
}
/*输出结果为
Other operation
2
1
2
Other operation
4
*/
在本例中Closure类实现了Incrementable,可以回调Callee2的increment()方法。这是Java中闭包的优点:无论谁获得此Incrementable的引用,都只能调用increment()方法,而不像指针那样可以做很多其他的事情。