适配器模式:
适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
所包含角色:
Target:目标抽象类
Adapter:适配器类
Adaptee:适配者类
Client:客户类
角色实例解读: 220V电压,5V电压,电压转换器需要将220V电压转换为5V电压给手机充电。在这个过程中。电压转换器充当适配器,将220V转换到5V,那么Adaptee就是220V电压,即是被适配者,5V电压就是Target,即是适配者。。
第一种:类适配器
Adapter直接继承适配者类,继承的目的就是直接调用适配器类中的方法获取数据,然后在适配器类中进行适配。Adapter同时实现了Target接口,这样一来就可以在使用目标类调用方法时的时候直接传入适配器类对象即可,此时直接调用子类方法,看例子。
适配器类
package adapter;
public class VolitageAdapter extends Volitage220V implements Volitage5V{
//继承的缺点:由于此类继承了Volitage220V类,在Volitage220V中的所有方法属性都会被
//暴露出来,因此使用对象适配器方式进行关联。
@Override
public int output5V() {
int srcV=output220V();
System.out.println("输出电压5V");
return srcV/44;
}
}
适配器类是这里的关键,在适配器中很明显的发现此适配器通过继承了Volitage220V直接调用了父类方法获取源数据,然后通过加工(srcV/44)
此句可以理解为适配过程,即对数据的处理。
被适配者
package adapter;
public class Volitage220V {
public int output220V(){
System.out.println("输出220V电压");
return 220;
}
}
目标类
package adapter;
interface Volitage5V {
int output5V();
}
调用者类
package adapter;
public class Phone {
public void charging(Volitage5V v){
int i = v.output5V();
System.out.println("充电:"+i+"V");
}
}
客户端
package adapter;
public class Clint2 {
public static void main(String[] args) {
Phone p=new Phone();
Volitage220V volitage220V = new Volitage220V();
p.charging(new VolitageAdapter2(volitage220V));
}
}
上方例子流程解释:手机需要用5V电压充电,在充电的时候(charging方法调用)就需要一个Volitage5V对象传入,客户端对手机进行充电时就可以传入一个VolitageAdapter调用这个类的充电方法进行充电。
第二种:对象适配器
对象适配器的实现就是,由适配器继承被适配者类改为关联一个被适配者类对象,在适配器初始化的时候对被适配者类进行初始化。
适配器类
package adapter;
public class VolitageAdapter2 implements Volitage5V{
//通过关联的形式使用Volitage220V,还需要在创建适配器时,传入一个src的对象即可。当然也可以利用set方法进行赋值。
Volitage220V volitage220V;
public VolitageAdapter2(Volitage220V volitage220V) {
this.volitage220V = volitage220V;
}
@Override
public int output5V() {
int i = volitage220V.output220V();
int a = i/44;
System.out.println("adapter2输出"+a+"V");
return a;
}
}
很明显在使用适配器的时候需要传入一个被适配者类(Volitage220V)
客户端
package adapter;
public class Clint2 {
public static void main(String[] args) {
Phone p=new Phone();
//调用时需要传入一个被适配者
Volitage220V volitage220V = new Volitage220V();
p.charging(new VolitageAdapter2(volitage220V));
}
}
两者的区别:
1,在对象适配器中由于继承了被适配者,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
2,与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。
类适配器中直接继承了被适配者,因此当被适配者方法改变时,适配器类为其子类直接可以重写即可。相反,对象适配器就需要重新继承被适配者,然后适配器中使用被适配者。
第三种:接口适配器
在前两者的基础上发展来,在适配器和目标类之间加了一层Abstract类,目的是方便适配器的使用,使用适配器时不需要实现所有没必要方法。具体实现:
目标了为接口。写个Abstract类实现接口,并实现其方法,全部为空方法。具体适配器只需要继承这个类即可,并且可以选择需要的方法进行实现。
转载:https://blog.csdn.net/weixin_42051691/article/details/106002874