适配器模式,顾名思义,就是把原本不兼容的接口,通过适配,使之兼容。

举个生活中简单的例子,以前的手机内存卡可以取出来,但是想和电脑之间传输音乐、视频等资料不能直接传输,需要通过USB读卡器,然后插入USB接口就可以传输了,这个USB读卡器就相当于适配器。

你经常使用的手机或电脑充电器,也属于适配器,它将220V的交流电转换为手机可用的直流电。下面,以手机充电器为例讲解适配器模式。

适配器模式一般分为三类:类适配器模式、对象适配器模式、接口适配器模式(缺省适配器模式)

一、类适配器模式

一般手机充电器输出的直流电压为5V,我们把交流电220V称为源,希望得到的直流电5V称为目标,而充电器即为适配器。

//源,交流电
public class AC {public int outputAC(){return 220;}
}
//目标接口,直流电
public interface IDC {public int outputDC();
}
//适配器
public class ClsAdapter extends AC implements IDC{@Overridepublic int outputDC() {return outputAC()/44;  //直流电为交流电的电压值除以44}public static void main(String[] args) {ClsAdapter adapter = new ClsAdapter();System.out.println("交流电电压:"   adapter.outputAC());System.out.println("直流电电压:"   adapter.outputDC());}
}/**
输出结果为:
交流电电压:220
直流电电压:5
*/

可以看到,类适配器是通过继承源类,实现目标接口的方式实现适配的。但是,由于Java单继承的机制,这就要求目标必须是接口,有一定的局限性。

二、对象适配器模式

对象适配器,不是继承源类,而是依据关联关系,持有源类的对象,这也隐藏了源类的方法。在这里,适配器和源类的关系不是继承关系,而是组合关系。

public class ObjAdapter implements IDC {//持有源类的对象private AC ac;public ObjAdapter(AC ac){this.ac = ac;}public int outputAC(){return ac.outputAC();}@Overridepublic int outputDC() {return ac.outputAC()/44;}public static void main(String[] args) {ObjAdapter adapter = new ObjAdapter(new AC());System.out.println("交流电电压:"   adapter.outputAC());System.out.println("直流电电压:"   adapter.outputDC());}
}
//输出结果同上

三、接口适配器模式

设想,我现在的目标接口有多个方法,可以输出5V,12V,20V的电压。按照正常逻辑,设计一个适配器去实现这个接口,很显然需要实现所有的方法。但是,实际使用中,其实只需要使用其中一个方法就可以了,比如我mac电脑直流电压20V,只需要实现20V的方法就可以了。

因此,设计一个中间类去把目标接口的所有方法空实现,然后适配器类再去继承这个中间类,选择性重写我所需要的方法,岂不是更好。代码如下,

//目标接口,有多个方法
public interface IDCOutput {public int output5V();public int output12V();public int output20V();
}
//中间类,空实现所有方法,这是一个抽象类
public abstract class DefaultAdapter implements IDCOutput {@Overridepublic int output5V() {return 0;}@Overridepublic int output12V() {return 0;}@Overridepublic int output20V() {return 0;}
}
//我的mac电源适配器只需要实现20V的方法即可
public class MacAdatper extends DefaultAdapter {private AC ac;public MacAdatper(AC ac){this.ac = ac;}@Overridepublic int output20V() {return ac.outputAC()/11;}public static void main(String[] args) {MacAdatper adatper = new MacAdatper(new AC());System.out.println("mac电脑电压:"   adatper.output20V());}
}
//输出结果:
//mac电脑电压:20

至于为什么中间类使用抽象类,相信你看过我介绍的软件六大设计原则,就明白了。它需要符合里氏替换原则(尽量基于抽象类和接口的继承)。

不太明白接口适配模式的童鞋,建议看一下JDK里边提供的一个键盘监听适配器KeyAdapter,它就是一个抽象类,去空实现了KeyListener接口的所有方法。你就会感受到这种模式的奥妙。

总结:

  1. 类适配器模式,继承源类,实现目标接口。
  2. 对象适配器模式,持有源类的对象,把继承关系改变为组合关系。
  3. 接口适配器模式,借助中间抽象类空实现目标接口所有方法,适配器选择性重写。

三种模式,各有优缺点,可根据实际情况选择使用。

适配器模式的三种形式相关推荐

  1. FMDB使用的数据库的三种形式

    FMDB使用的数据库的三种形式 FMDB是iOS平台下一款优秀的第三方SQLite数据库框架.它以Objective-C的方式封装了SQLite的C语言API.使用起来,它更加面向对象,避免冗余的C语 ...

  2. 批量梯度下降 linux,梯度下降的三种形式BGD,SGD,MBGD(MSGD)

    梯度下降的三种形式BGD,SGD,MBGD: Batch gradient descent: Use all examples in each iteration: Stochastic gradie ...

  3. 1. 变量提升 2. 条件语句 3. 循环语句 弹出框的三种形式 If条件的种类...

    1.     变量提升 变量提升是浏览器的一个功能,在运行js代码之前,浏览器会给js一个全局作用域叫window ,window分两个模块,一个叫内存模块,一个叫运行模块,内存模块找到当前作用域下的 ...

  4. java光标移动函数_文件内光标的移动 函数基础 定义函数的三种形式 函数的返回值 调用方式...

    # with open(r'a.txt', 'r', encoding='utf-8')as f: # data1=f.read() # print('>1>:',data1) # pri ...

  5. 创建Git仓库的三种形式

    创建Git仓库的三种形式: 2种本地创建和远程拉取 文章目录 1. 在idea中初始化仓库 1.1. 进入目录,初始化仓库 1.2. git init 目录名 1.3.1 远程拉取 1. 在idea中 ...

  6. 梯度下降法的三种形式批量梯度下降法、随机梯度下降以及小批量梯度下降法

    梯度下降法的三种形式BGD.SGD以及MBGD 梯度下降法的三种形式BGD.SGD以及MBGD 阅读目录 1. 批量梯度下降法BGD 2. 随机梯度下降法SGD 3. 小批量梯度下降法MBGD 4. ...

  7. php数组书写形式,php数组(array)输出的三种形式讲解

    php数组(array)输出的三种形式讲解 发布于 2015-01-30 15:57:43 | 119 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hyperte ...

  8. 自动回复的三种形式?

    自动回复的三种形式? 1.自动添加回复:粉丝添加时,自动的回复 2.关键词回复:消息里有关键词的回复,所自动回复消息回复 3.消息回复:粉丝发送没有关键词的,微信公众号自动的回复消息

  9. OCR识别技术 文档识别的三种形式

    如何将文档上的文字转换成可编辑的文字,通俗一点说,就是将纸质上的文字转换成电子版形式的文字内容: 文档识别通常有三种形式,其利用的核心技术都是OCR文字识别技术. 步骤如下: 一.通过扫描,识别文字信 ...

  10. java ajax 输出_正本清源:所谓Ajax输出的三种形式

    # re: 正本清源:所谓Ajax输出的三种形式  回复  更多评论 2005-12-30 23:19 by Vinson Buffolo did a great job to provide an ...

最新文章

  1. Mysql将SQL查询结果以字符串形式返回
  2. CPU制作流程大揭密
  3. 理解MySQL——并行数据库与分区(Partition)
  4. 【收藏】Oracle存储过程读写文件
  5. mysql数据库优化大全
  6. go 用 mysql web开发环境_简单讲解Go程序中使用MySQL的方法
  7. python异常值检测_python – 使用RPCA的异常值
  8. 发现 ASP.NET Core SignalR
  9. 程序员穿特步鞋相亲被拒!特步:怪我喽?
  10. xampp配置虚拟主机
  11. python编写登录接口_每日一题.PYTHON编写简单登录接口?
  12. 学生选课系统代码--分析1
  13. [5-24]绿色精品软件每天更新[uc23整理]
  14. ExcelJS 将JSON数组转换成为Excel文件 / JSON转换成为XLSX / 网页导出Excel表格
  15. IMDB TOP250中文版(截止2011.6.18)
  16. gif 格式图片详细解析
  17. 服务器连接电脑显示屏花屏怎么解决,电脑显示器花屏怎么办 电脑显示器花屏解决方法【详解】...
  18. Mac桌面莫名出现黑色输入框的关闭方法
  19. LODOP直接用base64码输出图片
  20. [流媒体]实例解析MMS流媒体协议,下载LiveMediaVideo[1][修正版,增加了带宽测试包]

热门文章

  1. node视频转码框架
  2. 中小卖家电商节恐惧症:你们剁手,我们割肉 2017-10-27 09:00 稿源:懂懂笔记 0条评论 撤稿纠错 “其实对一部分我们这样的中小卖家来说,造节就是煎熬。” 在某大型电商平台上拥有两家
  3. VB+ADO+Access如何修改数据
  4. 前端必备知识之 Nginx 复盘总结
  5. 37.WLAN Qos介绍
  6. javaScript常用案例
  7. pca人脸特征降维的过程理解及matlab编程实现
  8. 计算机类自主招生推荐信,自主招生推荐信范文15篇
  9. it行业发展前景怎么样?互联网寒潮来袭是真的吗?
  10. 中国农业大学计算机考研拟录取名单,中国农业大学2021年硕士生招生考试拟录取名单公示...