- 需要内部类原因:内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象。可以认为内部类提供了某种进入其外围类的窗口。每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象的信息相互独立。
2)在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
3)创建内部类对象的时刻并不依赖于外围类对象的创建。
4)内部类并没有令人迷惑的“is-a”关系,是一个独立的实体。
闭包与回调
- 闭包是一个可调用的对象,记录了一些信息,这些信息来自于创建它的作用于。通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有成员,包括private成员。
- 创建一个内部类时,并没有在外围类的接口中添加东西,也没有修改外围类的接口。
- 回调的价值在于它的灵活性,可以在运行时动态地决定需要调用什么方法,
interface Incrementable{void increment();}
class Callee1 implements Incrementable{
private int i=0;
@Override
public void increment() {
System.out.println("Callee1 increment()");
i++;
System.out.println(i);
}
}
class MyIncrement{
public void increment(){
System.out.println("Other operation");
}
static void f(MyIncrement myIncrement){myIncrement.increment();}
}
class Callee2 extends MyIncrement{
private int i=0;
public void increment(){
System.out.println("========");
super.increment();
i++;
System.out.println("Callee2 increment");
System.out.println(i);
}
private class Closure implements Incrementable{
@Override
public void increment() {
System.out.println("Closure increment");
Callee2.this.increment();
}
}
Incrementable getCallbackReference(){
return new Closure();
}
}
class Caller{
private Incrementable callbackReference;
Caller(Incrementable incrementable){callbackReference=incrementable;}
void go(){callbackReference.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);
Caller caller2=new Caller(callee2.getCallbackReference());
System.out.println("=====================");
caller1.go();
System.out.println("=====================");
caller1.go();
System.out.println("=====================");
caller2.go();
System.out.println("=====================");
caller2.go();
}
}