选抽象类还是接口取决于语义:表达“是什么”用抽象类,“能做什么”用接口;抽象类适用于有父子关系、共享状态或逻辑的场景,接口适用于定义能力契约、解耦和多实现。

选抽象类还是接口,关键看你要表达的是“它是什么”还是“它能做什么”。前者用抽象类,后者用接口。设计模式里它们各自承担不同角色,不是互斥,而是配合。
什么时候该用抽象类
当一组类有明确的父子关系,且共享状态或通用逻辑时,抽象类更自然。
- 需要定义构造器来初始化共用字段(比如
Animal(String name)) - 多个子类复用同一段实现(如
breath()、sleep()这类通用行为) - 想强制子类按固定流程执行(模板方法模式:把算法骨架写在抽象类里,留几个
abstract钩子让子类填) - 存在受保护的成员变量(如
protected int health),需要被子类直接访问
什么时候该用接口
当你关注能力契约,而非血缘关系;尤其需要一个类具备多种不相关能力时,接口是唯一选择。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 跨继承体系的行为统一(比如
Comparable、Serializable、Cloneable) - 一个类要同时拥有飞行+游泳+发声能力(
implements Flyable, Swimmable, Vocal) - 解耦调用方与实现方(依赖倒置:Service层只面向
PaymentStrategy接口编程,不关心是微信还是支付宝) - 为测试或替换提供扩展点(Mock实现接口,无需改动原有类结构)
设计模式中的典型配合方式
抽象类和接口常一起用,各司其职:
立即学习“Java免费学习笔记(深入)”;
-
模板方法模式:抽象类定义流程骨架(
execute()),子类实现钩子方法;接口可作为其中某一步的策略(如Validator接口供不同校验逻辑注入) -
策略模式:策略本身用接口定义(
DiscountStrategy),而具体策略若需共享计算逻辑,可用抽象类作为基类(如AbstractPercentageDiscount) -
工厂方法模式:工厂类常用抽象类(含通用创建逻辑),产品类型则通过接口暴露能力(如
Product接口,Phone和Laptop各自实现) -
观察者模式:观察者统一实现
Observer接口,被观察者内部用抽象类封装注册/通知基础机制
Java版本演进带来的影响
Java 8 加入default和static方法后,接口也能提供默认行为,但本质没变:
-
default方法用于向后兼容(如Collection新增stream()),不是为了替代抽象类的复用场景 - 接口仍不能有实例变量、不能有构造器、所有字段仍是常量——这些硬约束决定了它无法承担“状态+行为”的复合职责
- 如果发现接口里堆了太多
default方法,还带复杂状态管理,那大概率该重构为抽象类了

















