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

如何在不违反SOLID原则下正确修改子类Knight的attack字段值?

问题解答

首先明确:绝对不要把attack字段改成public。直接暴露私有字段会彻底破坏封装性——后续如果要给attack添加校验逻辑(比如限制攻击值不能为负),你得修改所有直接访问这个字段的代码,完全违反了SOLID中的开闭原则(OCP),也违背了面向对象设计的核心思想。

你的现有代码能实现需求,但确实有更优雅且符合SOLID的优化方案:

更优实现:使用父类参数化构造器

核心思路是让父类Warrior提供带参数的构造器,子类Knight通过调用这个构造器直接初始化正确的属性值,避免先设默认值再修改的冗余操作,同时保留封装性。

优化后的Warrior类

public class Warrior {
    private int health;
    private int attack;

    // 无参构造器,使用默认属性值
    public Warrior() {
        this(50, 5);
    }

    // 受保护的参数化构造器,允许子类定制初始属性
    protected Warrior(int health, int attack) {
        this.health = health;
        // 可在此添加属性校验逻辑,比如攻击值不能为负
        if (attack < 0) {
            throw new IllegalArgumentException("攻击值不能为负数");
        }
        this.attack = attack;
    }

    // 提供getter方法供外部访问属性(按需保留)
    public int getAttack() {
        return attack;
    }

    // 如果攻击值不需要后续修改,建议移除setAttack方法,强化封装
    // public void setAttack(int attack) {
    //     this.attack = attack;
    // }
}

优化后的Knight类

public class Knight extends Warrior {
    public Knight() {
        // 直接调用父类构造器,传入骑士的专属攻击值7,生命值沿用父类默认的50
        super(50, 7);
    }
}

为什么这个方案更符合SOLID?

  • 开闭原则(OCP):父类通过参数化构造器开放了定制扩展点,子类无需修改父类内部逻辑就能实现属性定制;后续如果要添加属性校验,只需在父类构造器中修改,不影响所有子类。
  • 封装性:字段始终保持private,不会暴露给外部代码,避免了随意修改属性的风险。
  • 代码简洁性:跳过了先初始化默认攻击值再修改的冗余步骤,直接一步到位完成正确初始化。

内容的提问来源于stack exchange,提问作者Fellou98

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:50:24