java面向对象基础:适配器设置模式之接口适配器
在软件开发的过程中,我们常常会遇到这样一种情况:已有的接口与新需求的接口不兼容(例如:手头有一个功能完善的类,但它的接口(方法签名、参数等)和我们当前使用的系统不兼容),但我们又不能直接修改已有代码(因为可能会影响其他模块,或这些代码来自第三方库)。此时,就需要用到设计模式中的 适配器模式(Adapter Pattern) 来解决接口不匹配的问题。
简单理解:设计模式就是各种套路。
1. 适配器模式的概念与作用
适配器模式是 结构型设计模式 之一,它的核心思想是:将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
换句话说,它就像生活中的“电源适配器”:笔记本电脑需要 20V 电压,而墙上的电源是 220V,通过适配器,就能把 220V 转换成 20V,从而使设备正常工作。
在 Java 中,适配器模式常用于以下情况:
接口方法过多:当一个接口中包含很多抽象方法,而实现类只需要其中部分功能时,直接实现接口会显得冗余。
接口不兼容:已有的接口与目标使用者的需求不一致,需要通过一个“中间层”来进行方法兼容或转化。
2.适配器模式的三种常见实现
类适配器(Class Adapter)
通过 继承 来实现适配。通常是:适配器类 继承被适配者(已有类)
同时 实现目标接口
依靠“多重身份”在两者之间做桥接。
局限性:因为 Java 不支持多继承,一个类只能继承一个父类,所以类适配器的应用场景比较有限。
对象适配器(Object Adapter)
通过 组合 来实现适配。适配器类 实现目标接口
在内部持有一个“被适配者”的实例
调用时,把请求委托给这个内部对象完成。
接口适配器(Interface Adapter,也叫 Default Adapter)
当目标接口方法过多,而实现类只需要部分功能时:定义一个 抽象适配器类,实现目标接口,并对所有方法给出 空实现。
具体的实现类只需继承这个抽象适配器类,并 选择性地重写需要的方法。
3.接口适配器的实现步骤
定义接口
创建一个接口,包含若干抽象方法。编写适配器类
2.2 使用
2.1 创建一个Adapter
类,实现该接口,并对所有方法提供空实现。abstract
修饰该类,避免被直接实例化。编写实现类
让真正的实现类继承适配器类,根据需要选择性地重写某些方法。测试调用
创建实现类对象,只调用需要的方法即可。
4.代码示例
1. 目标接口(Target Interface)
package interfaceDemo4;public interface inter {public abstract void method1();// ... method2() 到 method9() 略public abstract void method10(); // 接口中定义了10个抽象方法
}
2. 适配器类(中间层,推荐使用抽象类)
package interfaceDemo4;// 推荐使用 abstract 关键字修饰,防止被实例化
public abstract class TestAdapter implements inter{ @Overridepublic void method1() {// 抽象适配器类:提供空实现,避免实现类必须实现所有方法}@Overridepublic void method2() {// 空实现}// ... method3() 到 method10() 均为{}空实现// 省略所有方法的空实现
}
3. 实现类(按需重写)
package interfaceDemo4;public class MyTest extends TestAdapter{// 需要用到哪个方法就重写哪个方法@Overridepublic void method5() {System.out.println("只用方法5");}// 自动继承了 TestAdapter 中其他方法的空实现
}
4. 测试类
package interfaceDemo4;public class Test {public static void main(String[] args) {MyTest mt = new MyTest();mt.method5(); // 输出: 只用方法5// 尽管没有重写,也可以调用其他方法,但不会有任何操作mt.method1(); // 不会输出任何内容}
}
5. 适配器模式的优缺点
优点:
解耦:将接口与实现类解耦,避免冗余代码。
灵活性:子类只需重写需要的方法,避免实现所有接口方法。
代码简洁:适合接口方法较多而实现类只需要部分方法的情况。
缺点:
增加类层次:需要引入一个中间适配器类,会使类的层次结构更复杂。
不适合所有场景:如果接口方法不多,直接实现接口即可,无需适配器。