1.概述
在编程中,每个程序员都可能会遇到这样的问题:方法a()需要A类型的参数,然而我想让B类型的对象作为方法a()的参数进行传递并调用B中定义的方法,A,B两个类型完全不兼容,如何实现这个需求呢?这时就需要适配器出场了。
2.定义
适配器模式,是指将一个接口类型转化为另一个接口类型,从而可以让原本不兼容的类可以合作无间。
3.使用场景
当方法参数和现有实参类型不匹配时,需要创建适配器进行接口类型的转换。
4.UML图
适配器模式可以又可以分为两种:对象适配器和类适配器。
- 对象适配器:使用对象组合的方式,以修改的接口包装被适配者。其UML图如下:
- 类适配器:以类多继承的方式,以一个接口来适配另一个接口。由于使用多继承,因此这种适配器不适用于java。其UML图如下:
5.示例
5.1.对象适配器的用法
有两种充电器,分别用于给IPhone设备和Android设备充电:
/**
* Android 充电器
*
*/
public class AndroidCharger {
public void chargeForAndroid() {
System.out.println("Charging By AndroidCharger start...");
}
}
/**
* IPhone充电器
*/
class AppleCharger {
public void chargeForIPhone() {
System.out.println("Charged By AppleCharger start...");
}
}
/**
* IPhone手机实体类
*
*/
class IPhone {
private AppleCharger mCharger;
public void setCharger(AppleCharger mCharger) {
this.mCharger = mCharger;
}
public void plug() {
if (mCharger != null)
mCharger.chargeForIPhone();
}
}
/**
* Android实体类
*/
class Android {
private AndroidCharger mCharger;
public void setCharger(AndroidCharger mCharger) {
this.mCharger = mCharger;
}
public void plug() {
if (mCharger != null)
mCharger.chargeForAndroid();
}
}
先分别用各自充电器实现充电:
public class DemoAdapter {
public static void main(String[] args) {
//获取一个IPhone手机、IPhone充电器
IPhone iPhone = new IPhone();
AppleCharger appleCharge = new AppleCharger();
//插入充电器开始充电
iPhone.setCharger(appleCharge);
iPhone.plug();
//获取一个Android手机、Android手机充电器
Android android = new Android();
AndroidCharger androidCharger = new AndroidCharger();
//插入充电器开始充电
android.setCharger(androidCharger);
android.plug();
}
}
/*
运行结果:
Charging By AppleCharger start...
Charging By AndroidCharger start...
*/
那么问题来了,如果现在要给Android手机充电,但是没有充电器,怎么办呢?这时就需要一个适配器,然后将iPhone充电器适配给Andoird了:
/**
* 定义一个适配器,实现被适配者的接口(虽然这里是继承,但更推荐使用接口),将
* 适配者作为其组成之一
*/
class AndroidChargerAdapter extends AndroidCharger{
private AppleCharger mCharger;
public AndroidChargerAdapter(AppleCharger mCharger) {
this.mCharger = mCharger;
}
@Override
public void chargeForAndroid() {
// TODO Auto-generated method stub
System.out.println("Charging for Android by Adapter start....");
mCharger.chargeForIPhone();
}
}
再来使用适配器给Android手机充电:
public class DemoAdapter {
public static void main(String[] args) {
//获取IPhone充电器
AppleCharger appleCharge = new AppleCharger();
//获取一个Android手机、Android手机充电器
Android android = new Android();
//使用AppleCharger+适配器给Android手机充电
android.setCharger(new AndroidChargerAdapter(appleCharge));
android.plug();
}
}
该示例类图如下:
5.2.类适配器的用法
类适配器通过多继承实现,因此我们用C++来简单的实现一下上面的例子:
首先在头文件中定义相关类:
// adapter.h
#pragma once //Windows平台
#include <string>
//IPhone手机充电线
class AppleCharger
{
public:
AppleCharger() {}
virtual void charge();//需要重载
~AppleCharger() {}
};
//iPhone手机
class Apple
{
private:
AppleCharger* charger;
public:
void plug();
Apple(AppleCharger* charger);
~Apple() {}
};
//Android充电线
class AndroidCharger
{
public:
AndroidCharger() {}
~AndroidCharger() {}
virtual void charge();
};
//Android设备
class Android
{
private:
AndroidCharger* charger;
public:
explicit Android(AndroidCharger* charger);
~Android(){}
void plug();
};
//适配器类
class AndroidChargerAdapter :public AndroidCharger,public AppleCharger
{
public:
AndroidChargerAdapter() {}
~AndroidChargerAdapter() {}
void charge();
};
再来看实现:
#include <iostream>
#include "adapter.h"
void Apple::plug() {
charger->charge();
}
Apple::Apple(AppleCharger* charger)
{
this->charger = charger;
}
void AppleCharger::charge()
{
std::cout << "Charging by AppleCharger start..." << std::endl;
}
Android::Android(AndroidCharger* charger)
{
this->charger = charger;
}
void Android::plug()
{
charger->charge();
}
void AndroidCharger::charge()
{
std::cout << "Charging by AndroidCharger start..." << std::endl;
}
void AndroidChargerAdapter::charge()
{
std::cout << "Charging by AndroidChargerAdapter start..." << std::endl;
AppleCharger::charge();
}
最后来看main()函数中的使用:
#include <iostream>
#include "adapter.h"
int main()
{
//实例化适配器类对象
AndroidCharger* aca = new AndroidChargerAdapter();
Android* android = new Android(aca);
//给Android设备充电
android->plug();
system("pause");
return 0;
}
/*
运行结果:
Charging by AndroidChargerAdapter start...
Charging by AppleCharger start...
*/
该示例类图如下: