一、概述
- 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主要目的是兼容性,让接口不匹配不能工作的两个类可以协同工作,别名为包装类(Wrapper)
二、类适配器模式
- Adapter类,通过继承src类,实现dst接口,完成src->dst的适配
- 电源适配器例子:电源适配器
VoltageAdapter
继承Voltage220V
,实现Voltage5V
。
public class Voltage220V {
private final static int voltage = 220;
public static int output220V() {
return voltage;
}
}
public interface Voltage5V {
int output5V();
}
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int output5V() {
int vol = output220V();
int output = vol / 44;
if (output != 5) throw new RuntimeException("输入电压不符合");
return output;
}
}
public interface Phone {
void charge(Voltage5V voltage5V);
}
- Java是单继承机制,所以类适配器需要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性
- src类的方法在Adapter中会暴露,也增加了使用的成本
- 由于继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强
三、对象适配器模式
- 用关联关系(聚合)来替代继承关系,src类聚合到Adapter类中,而不是继承
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
public void setVoltage220V(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public int output5V() {
int vol = voltage220V.output220V();
int output = vol / 44;
if (output != 5) throw new RuntimeException("输入电压不符合");
return output;
}
}
四、接口适配器模式
- 又叫适配器模式或缺省适配器模式
- 核心思路:当不需要实现所有接口提供的方法时,先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
- 适用于不想实现接口所有方法的情况。收窄了接口
public interface Interface0 {
void m1();
void m2();
void m3();
void m4();
}
public abstract class AbsClass implements Interface0{
@Override
public void m1() {
throw new UnsupportedOperationException("Haven't overrider this method!");
}
@Override
public void m2() {
throw new UnsupportedOperationException("Haven't overrider this method!");
}
@Override
public void m3() {
throw new UnsupportedOperationException("Haven't overrider this method!");
}
@Override
public void m4() {
throw new UnsupportedOperationException("Haven't overrider this method!");
}
}
public class Interface0Impl extends AbsClass {
@Override
public void m1() {
System.out.println("调用m1方法");
}
public static void main(String[] args) {
Interface0 interface0 = new Interface0Impl();
interface0.m1();
interface0.m2();
}
}