Java中父类引用复用子类逻辑的核心是正确设计继承关系、合理使用多态并遵守里氏替换原则:父类引用指向子类对象时,调用方法实际执行子类重写版本,实现“用父类写法,跑子类实现”;通过抽象方法或钩子方法在模板流程中预留可变点,使子类仅需重写特定步骤即可复用整体逻辑。

Java 中通过父类引用复用代码逻辑,核心不在于“用父类引用调用子类方法”这种表面操作,而在于**正确设计继承关系 + 合理使用多态 + 遵守里氏替换原则**。父类引用本身不能直接“复用子类代码”,但它是触发多态、让子类逻辑被自动调用的关键桥梁。
父类引用指向子类对象,才能真正复用子类重写的逻辑
父类引用本身只定义了可见的方法签名,实际执行哪段代码,取决于它**运行时指向的对象类型**(即 new 出来的子类实例)。
- 声明父类引用: Animal a = new Dog();
- 调用方法:a.speak(); → 实际执行的是 Dog.speak(),不是 Animal.speak()
- 这就实现了“用父类的写法,自动跑子类的实现”,逻辑复用自然发生
把可变逻辑抽到抽象方法或钩子方法中
如果父类有通用流程(比如模板),但某些步骤因子类而异,就用抽象方法或钩子方法预留扩展点:
- 在父类中定义 final void process() { prepare(); doWork(); cleanup(); }
- 其中 doWork() 声明为 abstract 或默认空实现(钩子)
- 子类继承后只需重写 doWork(),父类的 process() 就能复用整个流程
避免在父类引用上调用子类特有方法
父类引用只能访问父类声明的方法和字段。若强行调用子类独有成员,编译不通过;若强制转型((Dog)a),会破坏多态初衷,也容易抛 ClassCastException。
立即学习“Java免费学习笔记(深入)”;
- 正确做法:把共性行为上提到父类(哪怕留空或抛 UnsupportedOperationException)
- 或者用组合+策略模式替代深度继承,更灵活安全
构造器中别依赖可被重写的方法
父类构造器执行时,子类对象尚未初始化完成。若父类构造器调用了被子类重写的方法,会调用子类版本——但此时子类字段还是默认值(0 / null),极易引发空指针或逻辑错误。
- 解决办法:构造器里只调用 private 或 final 方法
- 或把初始化逻辑延后到工厂方法、构建器中完成


















