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

Java中If条件判断异常:依赖倒置示例开关逻辑失效

依赖倒置原则实现中PowerSwitch无法正常切换状态的问题解决

你的代码里连续调用两次ClickSwitch()都输出"lamp's off",核心原因是子类重复定义了state字段,导致父类与子类的状态字段分离,PowerSwitch访问的父类状态从未被正确初始化和更新。

问题根源拆解

  1. 字段隐藏导致状态双份
    Switchable抽象类已经定义了public State state,但Lamp和Television子类又重新声明了同名的public State state。这是Java的字段隐藏机制,此时每个子类对象会同时持有父类和自己的两个state字段:
  • PowerSwitch里通过Switchable类型的引用,访问的是父类的state字段
  • 子类turn_on()/turn_off()方法修改的却是子类自己的state字段
  1. 父类状态未初始化
    Switchable的state字段没有初始化,默认值是null。每次ClickSwitch()判断sw.state == State.off时,null == State.off的结果都是false,所以每次都会执行turn_off(),自然两次都输出"lamp's off"。

修复方案

第一步:删除子类的重复state字段

直接去掉Lamp和Television里的public State state;声明,复用父类的state字段:

修改后的Lamp类:

public class Lamp extends Switchable {
    public Lamp() {
        state = State.off; // 直接初始化父类的state
    }

    public void turn_on() {
        this.state = State.on;
        System.out.println("lamp's on");
    }

    public void turn_off() {
        this.state = State.off;
        System.out.println("lamp's off");
    }
}

Television类顺便修正打印错误(把灯的输出改成电视的):

public class Television extends Switchable {
    public Television() {
        state = State.off;
    }

    public void turn_on() {
        this.state = State.on;
        System.out.println("television's on");
    }

    public void turn_off() {
        this.state = State.off;
        System.out.println("television's off");
    }
}

第二步:优化封装(可选但推荐)

为了遵循面向对象的封装原则,建议把state设为私有,通过get/set方法访问,避免直接操作字段:

修改Switchable抽象类:

public abstract class Switchable {
    private State state;

    protected void setState(State state) {
        this.state = state;
    }

    protected State getState() {
        return state;
    }

    abstract public void turn_on();
    abstract public void turn_off();
}

更新PowerSwitch的ClickSwitch()方法:

public void ClickSwitch() {
    if (sw.getState() == State.off) {
        sw.turn_on();
    } else {
        sw.turn_off();
    }
}

子类方法也改用get/set:

// Lamp类的turn_on示例
public void turn_on() {
    setState(State.on);
    System.out.println("lamp's on");
}

修复后运行结果

执行Main类代码,输出会变为:

lamp's on
lamp's off

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:12:04