You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:24:30