接口是行为契约,抽象类是共性模板;接口回答“能做什么”,抽象类回答“是什么”;选错类型会导致重构成本陡增,且受JVM语法铁律约束。

接口是行为契约,抽象类是共性模板
接口回答的是“它能做什么”,比如 Flyable、Serializable;抽象类回答的是“它是什么”,比如 Animal、Shape。选错类型会导致后期重构成本陡增——用接口强行塞状态字段,会暴露 public static final 常量的滥用;用抽象类替代多行为组合,会卡死继承链,无法再扩展其他能力。
- 当你需要让
Bird同时具备飞行、鸣叫、可序列化能力时,必须用接口(implements Flyable, Singable, Serializable),抽象类做不到这点 - 当你发现多个子类重复写
calculateArea()或共享color字段时,抽象类才是合理选择;接口里不能放private String color - Java 8+ 允许接口有
default方法,但别把它当抽象类用——default只用于向后兼容或极简逻辑,复杂实现仍该下沉到抽象类
构造器、字段、修饰符的硬性限制
这些不是设计风格差异,而是 JVM 层面的语法铁律,违反直接编译失败。
- 接口不能有构造器:写
interface A { A() {} }→ 报错Interface cannot have constructors - 接口字段自动被加上
public static final:写int x = 1;等价于public static final int x = 1;,想存实例状态?只能去抽象类 - 抽象方法的访问修饰符:抽象类中可用
protected abstract void init();,但接口中protected void fly();会编译报错——接口方法只能是public(且不能显式写出来)
继承与实现:单 vs 多的根本约束
这是 Java 类型系统最不可绕过的现实。不是“推荐”单继承,而是语言本身禁止:class Dog extends Animal, Mammal 是非法语法。
- 一个类只能
extends一个抽象类,但可以implements任意多个接口 - 接口之间支持多继承:
interface SmartDevice extends Connectable, Upgradable, Loggable合法;抽象类之间不行 - 如果已有类在继承链中(比如
class Button extends Component),又想赋予它点击、拖拽、可撤销等能力,只能靠接口——此时抽象类已无插足余地
默认方法不是万能补丁,滥用反而破坏语义
default 方法常被误当作“接口也能写实现”的信号,但它本质是妥协产物:为避免修改大量实现类而引入的向后兼容机制,不是设计新功能的首选路径。
立即学习“Java免费学习笔记(深入)”;
- 不要在接口里写带状态变更的
default方法,比如default void toggle() { this.enabled = !this.enabled; }—— 接口没有实例字段,这行代码根本通不过编译 - 多个接口含同名
default方法时,实现类必须显式覆写,否则编译错误:class X implements A, B中若A和B都有default void run(),X必须重写run() - 真正需要复用逻辑时,优先提取成工具类 + 静态方法,或用组合(如抽象类持有一个
Strategy接口),而非把业务逻辑塞进接口
















