Java中是否存在类似Smalltalk #implementedBySubclass的等价机制?
解决方案
1. 将AbstractEntity改为抽象类并声明抽象方法
这是Java中最直接且符合面向对象设计的方案——在AbstractEntity里把getQueuedActions()声明为抽象方法,这样编译器不会强制父类提供实现,反而会要求所有非抽象子类必须实现该方法,完美契合你“父类定义协议、子类提供实现”的需求。
示例代码:
// 抽象父类,定义通用逻辑和抽象方法 public abstract class AbstractEntity { public void moveTo(Target target) { // 这里写moveTo的通用逻辑 Actions actions = getQueuedActions(); // 继续执行后续通用逻辑... } // 声明抽象方法,由子类实现差异化逻辑 protected abstract Actions getQueuedActions(); } // NPC子类实现抽象方法 public class NPC extends AbstractEntity implements LifeForm { @Override protected Actions getQueuedActions() { // NPC专属的队列动作实现 return new NPCQueuedActions(); } } // Player子类实现抽象方法 public class Player extends AbstractEntity implements LifeForm { @Override protected Actions getQueuedActions() { // Player专属的队列动作实现 return new PlayerQueuedActions(); } }
2. 可选优化:用接口解耦行为(复杂场景适用)
如果后续getQueuedActions()的逻辑可能有更多变化维度,可以把这个行为提取为独立接口,通过组合或实现的方式解耦:
// 定义行为接口 public interface ActionQueueProvider { Actions getQueuedActions(); } // 抽象父类实现接口,复用moveTo逻辑 public abstract class AbstractEntity implements ActionQueueProvider { public void moveTo(Target target) { Actions actions = getQueuedActions(); // 通用逻辑... } } // NPC实现接口方法 public class NPC extends AbstractEntity implements LifeForm { @Override public Actions getQueuedActions() { return new NPCQueuedActions(); } }
为什么要避免instanceof?
instanceof硬编码判断违反了开闭原则——后续新增实体类型时,必须修改AbstractEntity的moveTo方法添加新分支,维护成本会越来越高,还容易遗漏逻辑。而抽象方法/接口的方式,新增子类只需实现对应方法,无需改动父类代码,扩展性更强。
内容的提问来源于stack exchange,提问作者Snorik
相关产品推荐
相关产品推荐

