适配器设计模式在Java中通过接口定义能力契约、抽象类提供空默认实现,使子类仅需重写关键方法;适用于回调监听等多方法可选场景,提升代码简洁性与可维护性。

适配器设计模式在 Java 中常通过抽象类与接口配合实现,核心思路是:用接口定义能力契约,用抽象类提供默认实现(尤其是空实现),让子类按需重写关键方法。这种方式特别适合回调监听、事件处理等存在大量可选方法的场景。
定义功能接口(契约层)
先声明一个接口,列出所有可能被调用的方法。例如模拟一个图形绘制系统:
public interface GraphicRenderer {
void onDrawStart();
void onDrawRect(int x, int y, int width, int height);
void onDrawCircle(int x, int y, int radius);
void onDrawEnd();
}
但实际使用中,多数用户只关心其中一两个方法(比如只关注 onDrawRect),直接实现该接口就得写四个空方法——冗余且易错。
编写抽象适配器类(默认实现层)
创建一个抽象类,实现该接口,并为所有方法提供空实现(或最简默认逻辑)。它不强制子类做任何事,只起“桥接”作用:
立即学习“Java免费学习笔记(深入)”;
public abstract class GraphicAdapter implements GraphicRenderer {
@Override
public void onDrawStart() {}
@Override
public void onDrawRect(int x, int y, int width, int height) {}
@Override
public void onDrawCircle(int x, int y, int radius) {}
@Override
public void onDrawEnd() {}
}
这个类本身不可实例化,但为具体使用者大幅降低实现成本。
子类按需继承并重写(定制层)
业务类只需继承 GraphicAdapter,仅覆盖真正需要响应的方法:
public class RectLogger extends GraphicAdapter {
@Override
public void onDrawRect(int x, int y, int width, int height) {
System.out.printf("记录矩形: (%d,%d), %dx%d%n", x, y, width, height);
}
}
// 使用示例
GraphicRenderer renderer = new RectLogger();
renderer.onDrawRect(10, 20, 100, 50); // 输出日志
renderer.onDrawCircle(0, 0, 30); // 无输出(空实现)
- 避免了接口实现类中大量
throw new UnsupportedOperationException()或空花括号 - 保持接口的开放性(未来新增方法只需在适配器里加空实现,不影响已有子类)
- 比直接用匿名内部类或 Lambda 更适合多方法、有状态的场景
进阶技巧:泛型适配器与组合式扩展
若需复用逻辑,可将适配器设计为泛型,或让其持有真实处理器对象(委托模式):
public abstract class DelegatingRenderer<T> implements GraphicRenderer {
protected final T context;
public DelegatingRenderer(T context) {
this.context = context;
}
@Override
public void onDrawRect(int x, int y, int width, int height) {
// 默认委托给 context 的 handleRect 方法(需类型支持)
}
}
这样既保留适配器的轻量性,又支持灵活注入行为。
这种“接口 + 抽象适配器”的组合不是语法强制,而是经验沉淀下来的简洁实践,本质是把“必须实现”降级为“可选覆盖”,让代码更聚焦于业务意图。


















