最近看了java编程思想一书,对内部类的设计感到惊叹,针对java采用内部类来实现回调比c语言更灵活(c语言通过指针来实现),下面博主分享下自己的一些心得,可能未必完全正确,如果有不对的地方,希望大家指出改正。
首先,要说的是内部类的特性,普通的成员内部类隐式链接到外部类,因此拥有外部类的所有元素的访问权的,正是因为这个特性,内部类对象也是一个闭包。闭包指的是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。利用闭包这个特性可以实现回调。回调可以简单理解为先将相关的方法实现好,但是并不由我来决定什么时候来调用它,而是通过程序在其他类对象运行时回头调用该类的方法。
下面看代码,用的是java编程思想的例子:
public interface Incrementable {
void increment();
}
/**
-
callee1 简单直接实现Incrementable 接口
*/
public class Callee1 implements Incrementable {
private int i = 0;@Override
public void increment() {
i++;
System.out.println(i);
}
}
public class MyIncrement {
public void increment() {
System.out.println(“other operation”);
}
static void f(MyIncrement mi) {
mi.increment();
}
}
/**
-
callee2不同于callee1
-
它里面使用了内部类从而可以回调自己的increment方法
*/
public class Callee2 extends MyIncrement {
private int i = 0;public void increment() {
super.increment();
i++;
System.out.println(i);
}private class Closure implements Incrementable{
@Override
public void increment() {
Callee2.this.increment();
}
}//私有的内部类要通过方法获取,也更有封闭性
Incrementable getCallback(){
return new Closure();
}
}
public class Caller {
private Incrementable callback;
public Caller(Incrementable callback) {
this.callback = callback;
}
void go(){
callback.increment();
}
}
public class Callbacks {
public static void main(String[] args) {
Callee1 callee1 = new Callee1();
Callee2 callee2 = new Callee2();
MyIncrement.f(callee2);
Caller caller1 = new Caller(callee1);
caller1.go();
caller1.go();
Caller caller2 = new Caller(callee2.getCallback());
caller2.go();
caller2.go();
}
}
在Caller里传递callee1和callee2的内部类Closure对象会有两种不同的效果,显然Closure内部类对象回头调用了callee2的方法,这就是回调!!不同于callee2自己调用increment方法。当然使用内部类的好处有很多,博主自己总结了以下几点:
1.多重继承
2.内部类和外部类之间相互独立互不影响
3.灵活,内部类和内部类间独立,比如一个类想使用迭代器,如果直接实现一个迭代器接口的话那么该类只能使用一种形式的迭代器,如果我想用从后往前的迭代方式往往不容易实现,如果用内部类的话就很好实现了不同形式的迭代器
4.封装细节,封闭性好
5.闭包与回调
6.控制框架的使用,这个博主打算某天用空单独解释该用处