定义
适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
适配器是什么,你一定不难理解,因为现实中到处都是。比方说,如果你需要在欧洲国家使用美国制造的笔记本电脑,你可能需要使用一个交流电的适配器。
你知道适配器的作用:它位于美式插头和欧式插座的中间,它的工作是将欧式插座转换成美式插座,好让美式插头可以插进这个插座得到电力。或者也可以这么认为:适配器改变了插座的接口,以符合美式笔记本电脑的需求。
实例
以之前讲过的鸭子为例。
public interface Duck {
public void quack();
public void fly();
}
绿头鸭是鸭子的子类。
public class MallardDuck implements Duck {
public void quack() {
System.out.println("Quack");
}
public void fly() {
System.out.println("I'm flying");
}
}
下面来看火鸡类:
public interface Turkey {
// 火鸡不会呱呱叫,只会咯咯叫
public void gobble();
// 火鸡会飞,虽然飞不远
public void fly();
}
火鸡实现类:
public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("Gobble gobble");
}
public void fly() {
System.out.println("I'm flying a short distance");
}
}
现在,假设你缺鸭子对象,想用一些火鸡对象来冒充。显而易见,因为火鸡的接口不同,所以我们不能公然拿来用。那么,就写个适配器吧。
// 首先你需要实现想转换成的类型接口,也就是你的客户所期望看到的接口。
public class TurkeyAdapter implements Duck {
Turkey turkey;
// 接着,需要缺德要适配的对象引用,这里我们利用构造器取得这个引用。
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
// 现在我们需要实现接口中所有的方法。
public void quack() {
turkey.gobble();
}
// 固然两个接口都具备了fly()方法,火鸡的飞行距离很短,不像鸭子可以长途飞行。
// 要让鸭子的飞行和火鸡的飞行能够对应,必须连续五次调用火鸡的fly()来完成。
public void fly() {
for(int i=0; i < 5; i++) {
turkey.fly();
}
}
}
小结
-
当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
-
适配器改变接口以符合客户的期望。
-
实现一个适配器可能需要一番功能,也可能不费功夫,视目标接口的大小与复杂度而定。
-
适配器模式有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。