Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比

发布时间 - 2026-01-10 21:50:54    点击率:

Java 适配器模式

           最近学习java 基础知识,学习适配器的时候疑惑很多,上网查下资料,对于 Adapter的资料很多,但是比较下本篇不错,这里记录下,大家需要的可以看下。

适配器模式就是把一个类的接口转换成客户端所期待的另外一种接口,从而使原接口不匹配而无法在一起工作的的两个类能在一起工作。从功能上说,这些接口不兼容的类一般具有相同或相似的功能。通常我们通过修改该类的接口来解决这种接口不兼容的情形,但是如果我们不愿意为了一个应用而修改各原接口,或者我们压根儿就没有对象的源代码的时候,适配器模式就会派上用场了。

适配器的优点:

1、将目标类和适配者类解耦

2、增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性

3、灵活性和扩展性都非常好,符合开闭原则

适配器所涉及的角色包括下面几种:

目标(Target):定义一个客户端使用的特定接口。

客户端(Client):使用目标接口,与和目标接口一致的对象合作。

被适配者(Adaptee):一个现存需要适配的接口。

适配器(Adapter):负责将Adaptee的接口转换为Target的接口。适配器是一个具体的类,这是该模式的核心

适配器分为类适配器和对象适配器两种,下面将详细讲述。

类适配器

所谓类适配器,指的是适配器Adapter继承我们的被适配者Adaptee,并实现目标接口Target。由于Java中是单继承,所以这个适配器仅仅只能服务于所继承的被适配者Adaptee。代码如下:

被适配者(Adaptee)

package com.bluemsun.classadapter;

public class Person {
  private int id;
  private String name;
  /**
   * person可以现在只能说英语
   */
  public void sayEnglish(){
    System.out.println("Person can say english!");
  }
  
  /**
   * 省略setter,getter.
   */
}

目标接口(Target)

package com.bluemsun.classadapter;

/**
 * 目标要求person可以说英语,法语,日语.但是现在的person仅仅可以说英语
 * @author Administrator
 *
 */
public interface Target_Person {
  void sayEnglish();
  void sayFrench();
  void sayJapanese();
}

适配器(Adapter)

package com.bluemsun.classadapter;

/**
 * 类适配器,因为继承了Person,而Java中只能单继承,所以这个适配器只为person这一个类服务
 * 这个适配器就让person类在不修改源码的基础上能实现目标接口所指定的方法
 * @author Administrator
 *
 */
public class Adapter_Person extends Person implements Target_Person{

  @Override
  public void sayFrench() {
    System.out.println("Person can say French!");
  }

  @Override
  public void sayJapanese() {
    System.out.println("Person can say Japanese!");
  }
}

客户端(Client)

package com.bluemsun.classadapter;

public class Test {
  public static void main(String[] args) {
    Target_Person person = new Adapter_Person();
    
    person.sayEnglish();
    person.sayFrench();
    person.sayJapanese();
  }
}

上面的几段简单代码演示了类适配器的作用。正如我们开始所言,这个适配器Adapter只能为Person这一个类所服务。这时候你可能会想,要是我所需要适配的类很多,是不是都需要为每一个需要适配的类写一个Adapter?有没有更加灵活的方式呢?答案是:有!就是我们下面所讲的对象适配器。

对象适配器

所谓对象适配器,简单的说就是适配器实现我们的目标接口,但是并不继承需要被适配的类。而是通过在适配器的构造函数中将需要被适配的类传递进来从而进行适配。代码如下:(Target,Adaptee同上)

适配器(Adapter)

package com.bluemsun.objectdapter;

import com.bluemsun.classadapter.Person;
import com.bluemsun.classadapter.Target_Person;

/**
 * 对象适配器,与类适配器不同的是:对象适配器可以适配多个源到目标
 * @author Administrator
 *
 */
public class Adapter_Person implements Target_Person{  //仅仅实现目标接口
  private Person person;
  
  //在构造函数中将Adaptee类Person传递进来
  public Adapter_Person(Person person){
    this.person = person;
  }

  //实现目标接口中的sayEnglish()--调用Adaptee中的sayEnglish()
  @Override
  public void sayEnglish() {
    this.person.sayEnglish();
  }

  //实现接口中的其它方法
  @Override
  public void sayFrench() {
    System.out.println("person can say French!");
  }

  @Override
  public void sayJapanese() {
    System.out.println("person can say Japanese!");
  }
}

客户端(Client)

package com.bluemsun.objectdapter;

import com.bluemsun.classadapter.Person;
import com.bluemsun.classadapter.Target_Person;

public class Test {
  public static void main(String[] args) {
    Target_Person person = new Adapter_Person(new Person());
    
    person.sayEnglish();
    person.sayFrench();
    person.sayJapanese();
  }
}

对象适配器可以适配多个带适配的类。只需要你在Adapter的构造方法中传递不同的带适配的类即可。具有灵活性。

类适配器的优点:

1、由于适配器类是适配者类的子类,因此可以再适配器类中置换一些适配者的方法,使得适配器的灵活性更强。

类适配器的缺点:

1、对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,不能为类,其使用有一定的局限性,不能将一个适配者类和他的子类同时适配到目标接口。

对象适配器的优点:

1、把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。

对象适配器的缺点:

1、与类适配器模式相比,要想置换适配者类的方法就不容易。

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Java  # 适配器模式  # 适配器模式对比  # Adapter  # 类与对象的对比  # 剖析Java中的事件处理与异常处理机制  # Java经典设计模式之适配器模式原理与用法详解  # 详解JAVA Spring 中的事件机制  # Java事件处理机制和适配器全面解析  # 客户端  # 多个  # 子类  # 英语  # 能为  # 这一  # 可以说  # 类中  # 复用  # 的是  # 不兼容  # 是一个  # 这是  # 法语  # 就会  # 日语  # 的说  # 就不  # 你在  # 两种 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在腾讯云服务器上快速搭建个人网站?  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  Python文件操作最佳实践_稳定性说明【指导】  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  Laravel如何使用Gate和Policy进行授权?(权限控制)  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  如何基于云服务器快速搭建个人网站?  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  Laravel如何与Inertia.js和Vue/React构建现代单页应用  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  js代码实现下拉菜单【推荐】  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  网站制作价目表怎么做,珍爱网婚介费用多少?  Laravel如何实现本地化和多语言支持?(i18n教程)  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  Laravel如何自定义分页视图?(Pagination示例)  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  如何在建站主机中优化服务器配置?  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  如何实现建站之星域名转发设置?  Win11怎么设置默认图片查看器_Windows11照片应用关联设置  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  如何彻底删除建站之星生成的Banner?  大连网站制作公司哪家好一点,大连买房网站哪个好?  JavaScript如何实现错误处理_try...catch如何捕获异常?  Laravel storage目录权限问题_Laravel文件写入权限设置  Laravel定时任务怎么设置_Laravel Crontab调度器配置  如何自定义建站之星网站的导航菜单样式?  微信小程序 input输入框控件详解及实例(多种示例)  如何确保西部建站助手FTP传输的安全性?  如何在IIS管理器中快速创建并配置网站?  Laravel观察者模式如何使用_Laravel Model Observer配置  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  详解jQuery中基本的动画方法  千库网官网入口推荐 千库网设计创意平台入口  简单实现Android验证码  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  Linux系统运维自动化项目教程_Ansible批量管理实战  MySQL查询结果复制到新表的方法(更新、插入)  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  SQL查询语句优化的实用方法总结  如何用PHP快速搭建高效网站?分步指南