extends 是 Java 实现单继承的强制语法,定义类型关系并影响多态与泛型;子类须显式调用 super(),private 成员不可继承,复用依赖可见性(如 protected)和构造器时机。

extends 是 Java 里实现类继承的唯一语法,不是可选项
Java 不支持多重继承,extends 是子类明确声明“我基于哪个父类构建”的强制语法。它不只是复用代码的手段,更是类型关系的定义——子类实例天然是父类类型的实例,这直接影响 instanceof 判断、多态调用和集合泛型约束。
常见错误是把 extends 当成“抄代码快捷键”:只复制方法,却忽略访问权限(private 成员不可继承)、构造器不自动调用、或误以为能 extends 多个类。
- 父类构造器不会被自动继承,子类必须显式调用
super(...)(哪怕只调super()),否则编译报错Implicit super constructor ... is undefined -
private字段和方法不可被子类访问,想复用就得改成protected或提供protectedgetter/setter - 一个类只能
extends一个直接父类,想组合多个能力,得靠接口implements+ 委托
子类复用父类共性代码的关键在“可见性+调用时机”
共性代码能否被复用,不取决于写在哪,而取决于它是否对子类可见,以及是否在合适时机执行。比如初始化逻辑放在父类构造器里,子类只要正确调用 super() 就自动执行;通用计算逻辑封装成 protected 方法,子类可直接调用或重写。
典型场景:多个业务实体都需要时间戳创建、ID 生成、基础校验。把这些抽到 BaseEntity 里,子类 extends BaseEntity 后,createdTime 字段和 validate() 方法就天然可用。
@Override
- 重写
toString()时,建议用super.toString() + ", name=" + name而非从头拼接 - 重写
hashCode()必须和equals()保持一致,且要包含父类参与计算的字段,否则放入HashSet会出问题 - 构造器里禁止调用可被重写的方法(包括
public/protected实例方法),因为此时子类字段还未初始化,可能引发 NPE 或逻辑错误
当 extends 不够用:组合优于继承的边界在哪
如果子类只需要父类的某几个功能,或者父类职责太重(比如 BaseService 里混了缓存、事务、日志、重试),强行 extends 会导致子类被拖累——明明只做简单查询,却要承担事务代理开销,还可能因父类 bug 被波及。
这时该用组合:private final CacheClient cache; + private final RetryTemplate retry;,按需装配,测试也更干净。JDK 自身也大量使用该模式,比如 ArrayList 内部用 Object[] 数组而非继承数组。
判断标准很简单:子类是不是“is-a”关系?Dog extends Animal 合理,PaymentService extends RedisCache 就荒谬——它只是用了 Redis,不是 Redis 的一种。










