将一个接口转换为客户但愿的另外一个接口,使接口不兼容的那些类能够一块儿工做,别名为包装器。java
适配器中的接口是广义的接口,能够表示一个方法或者方法的集合。ide
适配器模式既能够做为类结构型模式,也能够做为对象结构型模式。测试
根据适配器与适配者类的关系不一样,能够分为对象适配器模式以及类适配器模式。设计
对象适配器模式就是适配器与适配者之间是关联关系。3d
结构图以下:code
类适配器模式就是适配器与适配者之间是继承或实现关系。对象
结构图以下:blog
因为语言特性的限制,好比Java,C#不支持多重继承,类适配器模式受到不少限制,例如Target若是不是接口而是一个类,就没法使用类适配器模式。此外若是适配者为final
类也没法使用适配器模式,在Java等语言中大部分状况下使用对象适配器模式。继承
Target类以及实现了Target的类:接口
interface Target { void request(); } class ConcreteTarget implements Target { @Override public void request() { System.out.println("具体Target方法"); } }
适配者类:
class Adaptee { public void specificRequest() { System.out.println("Adaptee方法"); } }
适配器类(实现了Target,适配者做为成员变量):
class Adapter implements Target { private Adaptee adaptee = new Adaptee(); @Override public void request() { adaptee.specificRequest(); } }
测试:
public class Test { public static void main(String[] args) { Target target = new ConcreteTarget(); target.request(); Target adapter = new Adapter(); adapter.request(); } }
在上述对象适配器的基础上,适配者与Target保持不变,适配器继承了适配者并实现了Target,同时取消了适配者做为成员变量,在方法内直接调用super.xxx
,也就是适配者的方法:
class Adapter extends Adaptee implements Target { @Override public void request() { super.specificRequest(); } }
假设目前只有一条Micro USB线以及一台只有Type-C接口的手机,须要对其进行充电,这时候就须要一个转接头把Micro USB转为Type-C接口,才能给手机充电。
这里的Target就是Type-C,适配者就是Micro USB,适配器就是转接头,简化实现代码以下:
public class Test { public static void main(String[] args) { TypeC typeC = new MicroUSBToTypeC(); typeC.chargeWithTypeC(); } } //Target:给TypeC接口的手机充电 interface TypeC { void chargeWithTypeC(); } //Adaptee:适配者,MicroUSB线 class MicroUSB { public void chargeWithMicroUSB() { System.out.println("MicroUSB充电"); } } //Adapter:适配器,MicroUSB到TypeC的转接头 class MicroUSBToTypeC implements TypeC { private MicroUSB microUSB = new MicroUSB(); @Override public void chargeWithTypeC() { microUSB.chargeWithMicroUSB(); } }
在对象适配器的使用过程当中,若是在适配器中同时包含对Target类和Adaptee类的引用,Adaptee类能够经过适配器调用Target类中的方法,Target类也能够经过适配器调用Adaptee类的方法,那么该适配器就是一个双向适配器。例子以下:
public class Test { public static void main(String[] args) { Adapter adapter = new Adapter(); adapter.request(); adapter.specificRequest(); } } //适配者 interface Adaptee { void specificRequest(); } //Target类 interface Target { void request(); } //Target实现 class TargetImpl implements Target { @Override public void request() { System.out.println("Target方法"); } } //适配者实现 class AdapteeImpl implements Adaptee { @Override public void specificRequest() { System.out.println("Adaptee方法"); } } //适配器 class Adapter implements Adaptee,Target { private Target target = new TargetImpl(); private Adaptee adaptee = new AdapteeImpl(); @Override public void request() { //Target的方法调用适配者方法 adaptee.specificRequest(); } @Override public void specificRequest() { //适配者方法调用Target的方法 target.request(); } }
缺省适配器:当不须要实现一个接口所提供的全部方法时,可先设计一个抽象类实现该接口,并为接口中的每一个方法都提供一个默认实现(空实现),那么该抽象类子类能够选择性覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中全部方法的状况,又叫单接口适配器模式。
Java AWT中通常能够经过两种方式来处理窗口事件:
WindowListener
WindowAdapter
其中WindowAdapter
实现了WindowListener
接口,可是都是提供了空实现,也就是说实现WindowsListener
的话须要实现里面全部的方法,而继承WindowAdapter
只须要选择性地覆盖方法便可,结构图:
类适配器以及对象适配器的共同优势以下:
类适配器的独有优势以下:
对象适配器的独有优势以下:
类适配器缺点:
final
类,C#的sealed
类对象适配器缺点: