1. 可以实现多继承
我们知道,java中的类目前只支持单继承,即类只能有个直接父类。但如果我们想要继承两个抽象类,此时需要借助内部类实现。
如:
abstract class FlyingAnimal {
abstract void fly();
}
abstract class SwimmingAnimal {
abstract void swim();
}
/**
* Swan(天鹅)类既继承抽象类FlyingAnimal(飞行动物),又要继承SwimmingAnimal(游动物)
* @author zhoua
*
*/
public class Swan extends FlyingAnimal{
@Override
void fly() {
// TODO Auto-generated method stub
System.out.println("Swan.fly()");
}
void swim() {
this.getSwimming().swim();
}
SwimmingAnimal getSwimming() {
return new SwimmingAnimal(){
@Override
void swim() {
// TODO Auto-generated method stub
System.out.println("Swan.swim()");
}
};
}
public static void main(String[] args) {
Swan swan = new Swan();
swan.fly();
swan.swim();
}
}
在此例中,
Swan(天鹅)类既继承抽象类FlyingAnimal(飞行动物),又要继承SwimmingAnimal(游动物)。但Swan只能继承一个类FlyingAnimal,另一个类的继承与方法复写,只能在内部类中继承实现。所以在内部类中,通过getSwimming()方法,返回一个匿名内部类实例,并在Swan外部类中构造了swim()方法,来调用匿名内部类对象的swim()方法。
但是,这种设计方式,有明显的缺陷。因为,Swan类本身只继承了FlyingAnimal类,所以它和FlyingAnimal是is - a的关系,它和SwimmingAnimal并没有继承关系,所以并不是is-a的关系,其实更像一种has - a的关系。所以,这并不符合常理。
2. 使用"接口+内部类"的方式实现闭包与回调
概念可参考:https://www.cnblogs.com/pangblog/p/3359832.html
https://baike.baidu.com/item/%E9%97%AD%E5%8C%85/10908873?fr=aladdin#2
实例(来源于《think in java》):
interface Incrementable {
void increment();
}
class Callee1 implements Incrementable {
private int i = 0;
@Override
public void increment() {
// TODO Auto-generated method stub
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() {
// TODO Auto-generated method stub
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();
caller2.go();
}
}
在此例中,Callee1是简单的解决方式,直接实现了Incrementable接口,并复写了increment()方法。
Callee2则继承了MyIncrement(该类并未实现Incrementable接口,但也有increment()方法,该方法与Incrementable接口中的increment()方法毫不相干),就不能为了Incrementable的用途而复写increment()方法了。于是,只能使用内部类独立地实现Incrementable接口(接口+内部类)。