如何在不修改子类的前提下让Pet类扩展Animal子类并覆写指定方法?
解决方案:委托+继承实现自定义覆写与原有逻辑复用
针对需求,可通过委托模式(Delegation)结合继承实现:让Pet类继承Animal抽象类,内部持有一个Animal实例(即Cow或Pig对象),对需要自定义的方法(die()、dropLoot())直接覆写实现,对需要保留原有逻辑的方法(ai()、eat()),将调用委托给内部持有的实例。
代码实现示例
现有不可修改的类(仅作展示)
public abstract class Animal { public abstract void eat(); public abstract void ai(); public abstract void die(); public abstract void dropLoot(); } public class Cow extends Animal { @Override public void eat() { System.out.println("Cow eats grass"); } @Override public void ai() { System.out.println("Cow wanders around"); } @Override public void die() { System.out.println("Cow dies normally"); } @Override public void dropLoot() { System.out.println("Cow drops leather"); } } public class Pig extends Animal { @Override public void eat() { System.out.println("Pig eats slop"); } @Override public void ai() { System.out.println("Pig roots in dirt"); } @Override public void die() { System.out.println("Pig dies normally"); } @Override public void dropLoot() { System.out.println("Pig drops pork"); } }
Pet类实现
public class Pet extends Animal { private final Animal delegate; // 构造时传入要包装的Cow/Pig实例 public Pet(Animal delegate) { this.delegate = delegate; } // 委托原有逻辑的方法 @Override public void eat() { delegate.eat(); } @Override public void ai() { delegate.ai(); } // 自定义覆写的方法 @Override public void die() { System.out.println("Pet dies peacefully, no pain"); } @Override public void dropLoot() { System.out.println("Pet drops nothing (it's a companion)"); } }
使用方式
// 创建带Pet逻辑的Cow Animal petCow = new Pet(new Cow()); petCow.ai(); // 输出:Cow wanders around(复用Cow的ai实现) petCow.die(); // 输出:Pet dies peacefully, no pain(使用Pet的自定义逻辑) // 创建带Pet逻辑的Pig Animal petPig = new Pet(new Pig()); petPig.ai(); // 输出:Pig roots in dirt(复用Pig的ai实现) petPig.dropLoot(); // 输出:Pet drops nothing (it's a companion)(使用Pet的自定义逻辑)
方案说明
- 满足
Pet继承Animal的要求,可直接作为Animal类型使用; - 完全复用
Cow/Pig的原有方法实现,无需重复编写代码; - 可自由覆写指定方法,实现自定义业务逻辑;
- 无需修改
Cow和Pig的代码,符合需求限制。
为何之前的方案失败
- 泛型继承
Pet<T extends Animal> extends T:Java不支持泛型类继承类型参数,编译阶段会直接报错; - 普通包装类:若未继承
Animal,则无法作为Animal类型参与业务逻辑;若继承Animal但未委托所有未覆写的抽象方法,会导致类无法实例化(抽象方法未实现)。
内容的提问来源于stack exchange,提问作者The Justice King
相关产品推荐
相关产品推荐

