为什么需要内部类
- 完善多重继承
- 闭包与回调
多继承
坏处
- 因为某个功能或者属性而继承许多不必要的东西
- 继承的多个父类,可能出现同名方法或者属性,此时就会有歧义
内部类实现多继承
虽然C++的多继承一直被诟病,但有时是真的需要多继承来完成,Java中可以通过实现多个接口或者内部类来模拟多继承
Eraser抽象类
1
2
3public abstract class Eraser {
public abstract void erase();
}Pencil抽象类
1
2
3public abstract class Pencil {
public abstract void wirte();
}PencilWithEraser子类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package innerClass.meaning.mutiExtends;
/**
* Created by lqs on 2018/5/9.
*/
public class PencilWithEraser extends Pencil{
private MyEraser eraser = new MyEraser();
public void work() {
System.out.println("use to write");
}
/**
* 继承了橡皮擦的功能
*/
private class MyEraser extends Eraser {
public void work() {
PencilWithEraser.this.eraser();
}
}
private void eraser() {
System.out.println("use to erase");
}
public Eraser getEraser(){ //这里返回父类抽象类类型,因为内部类(子类)是private,外部无法访问里面的方法
return new MyEraser();
}
}Test测试
1
2
3
4
5
6
7public class Test {
public static void main(String[] args) {
PencilWithEraser pencilWithEraser = new PencilWithEraser();
pencilWithEraser.work();//write
pencilWithEraser.getEraser().work();//eraser
}
}
闭包和回调
什么叫闭包
闭包这个概念我第一次是在js这种动态语言获知的,很多语言都有闭包,简短的话来说,一个持有外部环境变量的函数就是闭包
回调
就不多解释了,A提供API给B调用,有时需要A在特定条件和时机调用B的方法。
一般使用一个库或类时,是你主动调用人家的API,这个叫Call,有的时候这样不能满足需要,需要你注册(注入)你自己的程序(比如一个对象),然后让人家在合适的时候来调用你,这叫Callback。
主体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68//接口
public interface Incrementable {
void increment();
}
// Very simple to just implement the interface
class Callee1 implements Incrementable {
private int i = 0;
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();
}
}
// If your class must implement increment() in
// some other way, you must use an inner class:
//既想实现接口又想继承,然而接口和父类都有相同名称的方法
class Callee2 extends MyIncrement {
private int i = 0;
public void increment() {
super.increment();
i++;
System.out.println(i);
}
//内部类实现接口
private class Closure implements Incrementable {
//实现方法在外部类里
public void increment() {
// Specify outer-class method, otherwise
// you'd get an infinite recursion
Callee2.this.increment();
}
}
//返回一个内部类的引用
Incrementable getCallbackReference() {
return new Closure();
}
}
//回调
class Caller {
//持有回调的引用
private Incrementable callbackReference;
Caller(Incrementable cbh) {
callbackReference = cbh;
}
void go() {
callbackReference.increment();
}
}测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class Callbacks {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
System.out.println("\n");
Caller caller1 = new Caller(c1);
Caller caller2 = new Caller(c2.getCallbackReference());
caller1.go();
caller1.go();
System.out.println("caller2");
caller2.go();
caller2.go();
}
}
内部类是面向对象的闭包,因为它不仅包含创建内部类的作用域的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。