抽象类可含非抽象方法以支持代码复用和部分实现,接口在java 8前仅含抽象方法以专注行为契约;java 8引入default方法是为兼容性扩展接口,而非替代抽象类。

抽象类中可以包含非抽象方法,是因为它本质还是“类”,承担着代码复用和部分实现的职责;接口在 Java 8 前只能有抽象方法,是因为它定位是纯粹的“行为契约”,不负责实现细节。
抽象类是类的半成品,天然支持具体逻辑
抽象类用 abstract class 声明,它保留了类的所有基本能力:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 可以定义构造器,用于子类初始化时执行共用逻辑(比如设置默认状态、校验参数)
- 可以声明普通字段(private/protected/public)、静态变量、实例变量
- 可以既有 abstract 方法(强制子类实现),也有已实现的普通方法(直接复用)
- 子类继承后,可直接调用这些已实现方法,无需重写
接口在 Java 8 前是纯契约,不带任何实现
接口用 interface 声明,设计初衷就是解耦“做什么”和“怎么做”:
- 所有方法默认是 public abstract,没有方法体,只规定签名
- 不能有构造器,也不能有实例变量;字段自动被 public static final 修饰,只能是常量
- 实现类必须覆盖全部方法(除非自己也声明为 abstract),否则编译不通过
- 这种严格性确保了不同类(哪怕毫无继承关系)只要实现同一接口,就能统一被当作某种能力来使用
Java 8 的 default 方法不是“破例”,而是补足现实需求
随着 API 演进,给已有接口新增方法会导致所有实现类编译失败。default 方法的引入,是为了在不破坏兼容性的前提下扩展接口:
- default 方法有方法体,实现类可选择是否重写
- 但它仍属于“契约层面的可选实现”,不是为了替代抽象类的复用角色
- 接口依然不能有构造器、不能有普通实例变量、不能有 protected/private 方法(Java 9 才支持 private default 方法,仅用于辅助其他 default 方法)
关键不在“能不能写方法”,而在“为什么这样设计”
抽象类回答的是:“这类东西一般怎么做事?” —— 提供骨架+共用逻辑
接口回答的是:“能做这件事,就叫具备这个能力” —— 只约定能力边界,不限定身份来源
所以 Animal 抽象类可以自带 sleep() 实现,而 Runnable 接口只说“你得提供 run()”,至于你是线程、定时任务还是按钮点击回调,它不管。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










