一、案例引入
家庭电压大小是220V,给手机充电时,我们不会直接将220V直接接到手机上,而是利用充电器的变压功能。让电压降到合适的范围上后,再去连接到手机上。充电器的这个功能就和适配器类似。但是适配器并不仅仅是用来降压的。这个模式是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。
二、类适配器
2.1、基本介绍
类适配器模式:将某个接口转换成客户端期望的另一个接口,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器。 适配器属于结构型模式。
2.2、适配器工作原理
2.3、解决上述案例
2.3.1、类图分析
2.3.2、代码实现
public class Voltage220v {
public int output ( ) {
System . out. println ( "源电压:" + 220 + "V" ) ;
return 220 ;
}
}
public interface Voltage5v {
public int getOutput5v ( ) ;
}
适配器类,通过继承的方式,从而获取到家庭原本的电压大小,再经过降压,使得电压大小符合手机充电。
public class VoltageAdapter extends Voltage220v implements Voltage5v {
@Override
public int getOutput5v ( ) {
int src = output ( ) ;
int ada = src / 44 ;
System . out. println ( "变压之后:" + ada + "V" ) ;
return ada;
}
}
手机类,给手机充电,传入适配器类,从而获取到合适的电压,
public class Phone {
public void charging ( Voltage5v voltage5v) {
voltage5v. getOutput5v ( ) ;
}
}
public class Client {
public static void main ( String [ ] args) {
Phone phone = new Phone ( ) ;
phone. charging ( new VoltageAdapter ( ) ) ;
}
}
2.4、类适配器的优缺点
Java是单继承机制,所以适配器需要继承被适配类这一点算是个缺点,因为这样,就要求最终的目标必须是通过接口传入,有一定的局限性。 通过继承的方式,使得被适配类的方法暴露在Adapter中。 但是,由于继承,所以可以根据需求重写被适配类的方法,使得Adapter类的灵活性增强。
三、对象适配器
3.1、基本介绍
对象适配器和类适配器很相似,通过上一个模式的分析,我们发现继承的方式有点不太好。所以,我们使用“合成复用原则 ”。
3.2、解决上述案例
3.2.1、类图实现
3.2.2、代码实现
被适配者和接口,和上面一样,就不再重复写。 适配器类
public class VoltageAdapter implements Voltage5v {
private Voltage220v voltage22v;
public VoltageAdapter ( Voltage220v voltage22v) {
this . voltage22v = voltage22v;
}
@Override
public int getOutput5v ( ) {
int ada = voltage22v. output ( ) / 44 ;
System . out. println ( "变压之后:" + ada) ;
return ada;
}
}
public class Phone {
public void charging ( Voltage5v voltage5v) {
voltage5v. getOutput5v ( ) ;
}
}
public class Client {
public static void main ( String [ ] args) {
Phone phone = new Phone ( ) ;
phone. charging ( new VoltageAdapter ( new Voltage220v ( ) ) ) ;
}
}
3.3、对象适配器的优缺点
对象适配器通过合成复用原则代替继承,所以解决了上一个模式出现的问题。bingqie也不再要求目标类必须是接口。 降低代码的耦合性,更加灵活。
四、接口适配器
4.1、基本介绍
接口适配器又被称为缺省适配器模式。 当不需要使用接口提供的全部方法时,可以通过设计一个抽象类实现接口,并且给实现的方法提供一个默认方法,那么该抽象类的子类就可以通过覆盖父类的某些方法来实现需求。
4.2、代码实现
public interface Interface {
void func1 ( ) ;
void func2 ( ) ;
void func3 ( ) ;
void func4 ( ) ;
}
public class ClassA implements Interface {
@Override
public void func1 ( ) {
}
@Override
public void func2 ( ) {
}
@Override
public void func3 ( ) {
}
@Override
public void func4 ( ) {
}
}
假设,我们现在只使用func1()。现在可以按照下列方式进行。
public class Test {
public static void main ( String [ ] args) {
ClassA classA = new ClassA ( ) {
@Override
public void func1 ( ) {
System . out. println ( "覆盖func1()" ) ;
}
} ;
classA. func1 ( ) ;
}
}