是决定花一段连续的时间把《Java编程思想》看一遍,看书怎么能不做笔记呢,明明知道自己有些地方看完肯定会忘掉的,所以想把每章的笔记重点放在博客上,与大家共享!
第十章 内部类
为什么需要内部类是我们首先需要明确的,如果没什么用,那没必要增加这个语言特性啊?
官方说来:内部类可以继承类或者实现接口,内部类的代码可以操作创建外围外部类的对象。换句话说,内部类提供了某种进入外部类的窗口。
这还不是最吸引人的,最吸引人的原因是:每个内部类都能独立的继承一个(接口的)实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
1.匿名内部类
就我个人而言,用的最多的还是匿名内部类,当然我是没见过什么世面,哈哈
在上一章 接口,我专门提到了接口与工厂,其实工厂模式用匿名内部类来实现的话,会变得更加简洁和美妙。
废话不多说,show you the code!
interface Service{
void method1();
void method2();
}
interface ServiceFactory{
Service getService();
}
class Implementation1 implements Service{
private Implementation1(){}
@Override
public void method1() {
System.out.println("Implementation1 method1");
}
@Override
public void method2() {
System.out.println("Implementation1 method2");
}
public static ServiceFactory factory =
new ServiceFactory(){
public Service getService() {
return new Implementation1();
}
};
}
s Implementation2 implements Service{
private Implementation2(){}
@Override
public void method1() {
System.out.println("Implementation2 method1");
}
@Override
public void method2() {
System.out.println("Implementation2 method2");
}
public static ServiceFactory factory =
new ServiceFactory(){
public Service getService() {
return new Implementation2();
}
};
}
s
}
public class Factories {
public static void serviceConsumer(ServiceFactory factory){
Service service = factory.getService();
service.method1();
service.method2();
}
public static void main(String[] args) {
serviceConsumer(Implementation1.factory);
serviceConsumer(Implementation2.factory);
}
}
2.闭包和回调
关于这个,也是看了好几遍才慢慢领会这样做的优势。
看代码更容易懂,最好能自己敲一下,打个断点,debug一下可能更清晰的明白程序的流程。
interface Incrementable{
void increment();
}
class Callee1 implements Incrementable{
private int i = 0;
@Override
public void increment() {
i++;
System.out.println(i);
}
}
class MyIncrement{
public void increment(){
System.out.println("Other operation");
}
static void f(MyIncrement mi){
mi.increment();
}
}
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 getCallbackReference(){
return new Closure();
}
}
class Caller{
private Incrementable callbackReference;
Caller(Incrementable cbh){
callbackReference = cbh;
}
void go(){
callbackReference.increment();
}
}
public class Callbacks {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
Caller caller1 = new Caller(c1);
Caller caller2 = new Caller(c2.getCallbackReference());
caller1.go();
caller1.go();
caller2.go();
caller2.go();
}
}
//output
/*
Other operation
1
1
2
Other operation
2
Other operation
3
*/
上面的代码进一步展示了外部类实现一个接口与内部类实现此接口之间的区别。
Callee1直接实现接口,就代码而言,最为简单。Callee2继承MyIncrement,与Incrementable有着完全不同的increment()方法,完全不相干。所以Callee2只能使用内部类独立实现Incrementable。
内部类Closure实现了Incrementable,以提供一个返回Callee2的“钩子”(hook)–而且是一个安全的钩子。无论谁获得此Incrementable的引用,都只能调用increment(),除此之外没有其他功能。
Caller的构造器需要一个Incrementable的引用作为参数,然后在以后的某个时刻,Caller对象可以使用此引用回调Callee类。