一、功能html
适配器模式把一个类的接口变换成客户端所期待的另外一种接口,从而使本来因接口不匹配而没法在一块儿工做的两个类可以在一块儿工做。java
二、模式中的角色app
适配器模式有类的适配器模式和对象的适配器模式两种不一样的形式,还有就是缺省适配模式。ide
三、缺省适配模式this
缺省适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型能够从这个缺省实现进行扩展,而没必要从原有接口进行扩展。做为适配器模式的一个特例,缺省适配模式在JAVA语言中有着特殊的应用。spa
咱们在SE开发中常常使用界面的关闭事件。htm
public TestWindowListener2() { setLayout(new FlowLayout(FlowLayout.CENTER)); add(new JButton("我是一个按钮")); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e)//窗口正处在关闭过程当中时调用 { System.out.println("我关"); System.exit(0); } } ); } |
WindowListener接口定义了一序列窗口事件。WindowAdapter抽象类实现了接口WindowListener的windowClosing 抽象方法的空实现(默认实现)public void windowClosing(WindowEvent e) {},这样客户端只须要继承适配器类,重写关注的接口代码便可!而不须要实现接口定义的每一个方法。在上面案例中windowClosing为咱们须要关注的方法重写该方法的实现便可,而不须要强制实现接口定义的其余方法好比windowOpened事件。对象
类的适配器模式和对象适配器模式能够参考博文http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html,我的以为写的仍是比较清楚的。blog
四、类的适配器模式继承
类的适配器模式把适配的类的API转换成为目标类的API。
在上图中能够看出,Adaptee类并无sampleOperation2()方法,而客户端则期待这个方法。为使客户端可以使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的:
模式所涉及的角色有:
● 目标(Target)角色:这就是所期待获得的接口。注意:因为这里讨论的是类适配器模式,所以目标不能够是类。
● 源(Adapee)角色:如今须要适配的接口。
● 适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不能够是接口,而必须是具体类。
public interface Target { /** * 这是源类Adaptee也有的方法 */ public void sampleOperation1(); /** * 这是源类Adapteee没有的方法 */ public void sampleOperation2(); } |
上面给出的是目标角色的源代码,这个角色是以一个JAVA接口的形式实现的。能够看出,这个接口声明了两个方法:sampleOperation1()和sampleOperation2()。而源角色Adaptee是一个具体类,它有一个sampleOperation1()方法,可是没有sampleOperation2()方法。
public class Adaptee { } |
适配器角色Adapter扩展了Adaptee,同时又实现了目标(Target)接口。因为Adaptee没有提供sampleOperation2()方法,而目标接口又要求这个方法,所以适配器角色Adapter实现了这个方法。
public class Adapter extends Adaptee implements Target { } |
五、对象适配器模式
与类的适配器模式同样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不一样的是,对象的适配器模式不是使用继承关系链接到Adaptee类,而是使用委派关系链接到Adaptee类。
从上图能够看出,Adaptee类并无sampleOperation2()方法,而客户端则期待这个方法。为使客户端可以使用Adaptee类,须要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类可以把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
public interface Target { /** * 这是源类Adaptee也有的方法 */ public void sampleOperation1(); /** * 这是源类Adapteee没有的方法 */ public void sampleOperation2(); } |
public class Adaptee { public void sampleOperation1(){} |
public class Adapter { private Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee = adaptee; } /** * 源类Adaptee有方法sampleOperation1 * 所以适配器类直接委派便可 */ public void sampleOperation1(){ this.adaptee.sampleOperation1(); } /** * 源类Adaptee没有方法sampleOperation2 * 所以由适配器类须要补充此方法 */ public void sampleOperation2(){ //写相关的代码 } } |