接口定义“能做什么”行为契约,抽象类定义“部分怎么做+必须做什么”骨架契约;接口支持多实现、无状态,抽象类支持单继承、可共享状态与构造逻辑。

Java 中接口和抽象类是定义面向对象契约的核心机制:接口声明“能做什么”,抽象类定义“部分怎么做+必须做什么”。二者配合使用,能清晰划清职责边界,提升代码可扩展性与可维护性。
用接口定义行为契约
接口是纯粹的行为协议,只包含 public abstract 方法(Java 8+ 可含 default 和 static 方法),不关心实现细节。它强制所有实现类提供统一的调用入口,实现“约定优于配置”。
- 用 interface 关键字定义,方法默认 public abstract,字段默认 public static final
- 一个类可 implements 多个接口,支持行为组合(如
Runnable & Serializable & Cloneable) - 推荐小而专注的接口(如
Comparable<t></t>、Iterable<t></t>),避免“胖接口” - 示例:定义支付能力契约
interface PaymentProcessor {<br> void process(double amount);<br> boolean isValid();<br>}
所有支付方式(WeChatPay、Alipay、CreditCard)都必须实现这两个方法,调用方无需知道具体类型。
用抽象类定义骨架契约
抽象类介于接口与具体类之间,既能声明抽象方法(强制子类实现),也能提供具体方法和共享状态,适合表达“是什么 + 部分怎么做”的层级关系。
- 用 abstract class 定义,可含构造器、字段、普通方法、抽象方法
- 一个类只能 extends 一个抽象类,但可同时 implements 多个接口
- 适合封装通用逻辑(如日志、校验、模板流程),把变化点留给子类实现
- 示例:定义动物基础契约
abstract class Animal {<br> protected String name;<br> public Animal(String name) { this.name = name; }<br> public void breathe() { System.out.println(name + " is breathing"); }<br> public abstract void makeSound(); // 子类必须实现<br>}
Dog 和 Cat 继承 Animal,复用breathe(),各自实现makeSound()。
接口 + 抽象类协同建模
真实场景中,常将接口定义顶层能力,抽象类实现共性逻辑,具体类完成定制——形成三层契约结构,兼顾灵活性与复用性。
立即学习“Java免费学习笔记(深入)”;
- 先设计接口(如
Shape),聚焦“有哪些操作”(area()、draw()) - 再写抽象类(如
AbstractShape),提供默认实现(toString())、校验逻辑或模板方法(render()调用validate()→draw()) - 最后由具体类(
Circle、Rectangle)继承抽象类并实现抽象方法 - 这样既保证所有图形可被统一处理(多态),又避免重复代码,还允许新增图形类型不破坏现有结构
选择原则:何时用接口?何时用抽象类?
关键看建模意图:
- 强调能力契约(“能不能做某事”)→ 优先接口(如
Logger、Filter) - 强调类型层次(“是什么,且有共同特征”)→ 选抽象类(如
InputStream、JFrame) - 需要共享状态(字段)或构造逻辑 → 只能用抽象类
- 未来可能需多继承行为 → 接口更灵活(Java 不支持多类继承)
- Java 8 后,接口 default 方法可提供简单默认实现,但不能有实例字段或构造器,仍无法替代抽象类的完整封装能力


















