“下面我们来讲面试必问系列”的第五种:适配器模式
“适配器”模式
概念:
所谓"适配",就是为了适配而适配.
所具有的的特殊类没有满足我想要的方法,那么就适配了
重要参数:
1.Adaptee:特殊”类”
2.Target:目标接口(有特殊方法,有我想要的方法)
3.Adapter:适配器类,”继承”了特殊类(就默认有了特殊方法),实现了目标接口,然后在重写一个我想要的方法即可.
使用该模式解决的问题:
1.将“某个类的接口”转换成为用户所期望的接口
2.目的: 消除由于接口不匹配造成的类的兼容性问题
“适配器模式”分为三类
- 1.类-适配器模式
- 2.对象-适配器模式
- 3.接口-适配器模式
1.类的适配器:
通过继承适配器特殊类,并实现目标接口的方法
- 1.Adapte:有特殊功能的(插座)类(但不满足我的插头)特殊方法1
- 2.Target:目标(我的,标准的插头)”接口”-标准方法2
- 3.ConcreatTartet:目标(我的插头的)接口的具体实现”类”-标准方法2
- 4.Adapter:适配”类”的”继承”(从而有了特殊功能)方法2(有特殊同能的类),实现了标准接口
代码
//具体存在的特殊的类,比如德国插座类,但不满足我带的"标准接口"的插座类
class Adaptee {
public void specificRequest() {
System.out.println("我是要被适配的类,我具有特殊功能");
}
}
//目标接口,标准接口,各种各样的接口,看你是哪一种
interface Target {
void request();
}
//具体的标准接口类,普通的功能
class ConcreateTarget implements Target {
@Override
public void request() {
System.out.println("我是普通类,具有普通功能");
}
}
//适配器类,具有了特殊类的功能(继承,就有了方法),并且"实现了标准的接口(之类对象-以后不同接口)",从而得到完整适配
class Adapter extends Adaptee implements Target {
@Override
public void request() {
//特殊的方法
super.specificRequest();
}
}
//测试类,用户
class Test {
public static void main(String[] args) {
//标准接口
ConcreateTarget target = new ConcreateTarget();
target.request();//标准功能
//适配后
Target adapter = new Adapter();
adapter.request();//适配功能
}
}
打印结果:
我是要被适配的类,我具有特殊功能
我是普通类,具有普通功能
以上的一部分人所认知的适配模式,而我只认为以下才是真正的适配模式:
- 1.我带着我的插”头”,来到德国宾馆,发现德国的插”座”是特殊的,不是标准的
- 2.我的目的就是找到一个”适配”插”座”,让它能插入德国的插座,我的插头能插入这个适配器.
参数:
通过幻想图片可知
- 1.Adaptee:已经放在德国宾馆的特殊的”插座”
- 2.Target:一个目标接口,目标就是我所期望的目标(声明了,可以擦特殊插座,并且有一个标准的插座)
- 3.Adapter:一个真正的目标具体实现类,就是真正的适配器,继承了特殊插座的功能,也有了标准接口的标准的方法,这个是重点
代码
//具体存在的特殊的类,比如德国插座类,但不满足我的标准插"头"
class Adaptee {
public void specificRequest() {
System.out.println("我是德国的\"特殊的插座\"-特殊的方法");
}
}
//目标接口,有"特殊插座"的方法,同样有"标准插座"的方法
interface Target {
void specificRequest();
void normalrequest();
}
//适配器类,具有了特殊类的功能(继承,就有了方法),并且"实现了标准的接口(之类对象-以后不同接口)",从而得到完整适配
class Adapter extends Adaptee implements Target {
@Override
public void normalrequest() {
System.out.println("我是具体的适配器,这是标准的\"插座\"-普通的方法");
}
}
//测试类,用户
class Test {
public static void main(String[] args) {
//看看用户只要拿到适配器,就可以看看他有什么功能
Target target = new Adapter();//指向子类对象
target.normalrequest();//适配功能
target.specificRequest();//适配功能
}
}
打印结果:
我是德国的\”特殊的插座\”-特殊的方法
我是具体的适配器,这是标准的\”插座\”-普通的方法
2.”对象”适配模式
- 概念:适配器不继承特殊类了,而是把”特殊类”改成写在成员变量,构造时赋值,只需改这一点即可
代码
//还是实现标准的接口,但是对于特殊类,在内部声明,并在构造的时候赋值,并有调用方法
class Adapter implements Target {
//内部声明
Adaptee adaptee;
//构造时赋值
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
//调用的方法
@Override
public void specificRequest() {
adaptee.specificRequest();
}
@Override
public void normalrequest() {
System.out.println("我是具体的适配器,这是标准的\"插座\"-普通的方法");
}
}
//测试类,用户
class Test {
public static void main(String[] args) {
//创建 特殊类
Adaptee adaptee = new Adaptee();
//看看用户只要拿到适配器,就可以看看他有什么功能
Target target = new Adapter(adaptee);//构造传入特殊类, 指向子类对象
target.normalrequest();//适配功能
target.specificRequest();//适配功能
}
}
打印结果同上
3.接口适配模式
为了不重写全部的接口,而多建立一个”抽象类”,然后适配器列继承”抽象类”,选择部分方法即可.
- 由于:当一个目标接口有”多个”方法,我们重写的时候,被要求都重写,这是比较浪费的
解决:
1.新建一个”抽象类”实现接口,就会有了接口的方法(抽象类继承接口不用写出来,自动了).
2.然后适配器”继承”相关的方法即可,这样就满足了我们只和继承抽象类的适配器接触即可结论:多了一层抽象类和抽象类接触.
代码
//一个接口,多个方法
interface Socket {
void SocketUSB();
void SocketPSP();
void SocketSONY();
void Socket3_0();
void Socket2_0();
}
//抽象类,去实现接口,重写所有方法,不写出来也有,如果有具体操作就重写
abstract class Socket_A implements Socket{
@Override
public void SocketUSB() {
}
@Override
public void SocketPSP() {
}
@Override
public void SocketSONY() {
}
@Override
public void Socket3_0() {
}
@Override
public void Socket2_0() {
}
}
//然后适配器 只要选择若干的方法即可,即继承抽象类的若干方法,就不用重写接口的所有方法了
class Adapter extends Socket_A{
//选择想要的方法
@Override
public void SocketUSB() {
System.out.println("适配器的-USB接口");
}
@Override
public void SocketSONY() {
System.out.println("适配器的-SONY接口");
}
}
//测试
class Test {
public static void main(String[] args) {
//指向子类对象
Socket sa = new Adapter();
sa.SocketUSB();
sa.SocketSONY();
}
}
打印结果:
适配器的-USB接口
适配器的-SONY接口
总结
重要参数:
1.Adaptee:特殊”类”
2.Target:目标接口(有特殊方法,有我想要的方法)
3.Adapter:适配器类,”继承”了特殊类(就默认有了特殊方法),实现了目标接口,然后在重写一个我想要的方法即可.
三类:
类适配器:特殊类,目标接口,适配器类继承和实现
对象适配器:特殊类放适配器里,从而少了继承,只需实现即可.
接口适配器:抽象类继承接口,适配器类继承抽象类若干方法