Java中If条件判断异常:依赖倒置示例开关逻辑失效
依赖倒置原则实现中PowerSwitch无法正常切换状态的问题解决
你的代码里连续调用两次ClickSwitch()都输出"lamp's off",核心原因是子类重复定义了state字段,导致父类与子类的状态字段分离,PowerSwitch访问的父类状态从未被正确初始化和更新。
问题根源拆解
- 字段隐藏导致状态双份
Switchable抽象类已经定义了public State state,但Lamp和Television子类又重新声明了同名的public State state。这是Java的字段隐藏机制,此时每个子类对象会同时持有父类和自己的两个state字段:
- PowerSwitch里通过
Switchable类型的引用,访问的是父类的state字段 - 子类
turn_on()/turn_off()方法修改的却是子类自己的state字段
- 父类状态未初始化
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
相关产品推荐
相关产品推荐

