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接口(接口+内部类)。