gpt4 book ai didi

Java 在初始化之前引用最终变量

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:09:05 26 4
gpt4 key购买 nike

我有这个父类(super class) Creature 及其子类 Monster。现在我有一个 final 变量在没有被初始化的情况下被引用的问题。

public class Creature {

private int protection;

public Creature(int protection) {
setProtection(protection);
}

public void setProtection(int p) {
if(!canHaveAsProtection(p))
throw new Exception();
this.protection = p;
}

public boolean canHaveAsProtection(int p) {
return p>0;
}
}

和子类:

public class Monster extends Creature {

private final int maxProtection;

public Monster(int protection) {
super(protection);
this.maxProtection = protection;
}

@Override
public boolean canHaveAsProtection(int p) {
return p>0 && p<maxProtection
}
}

如你所见,当我初始化一个新的Monster时,它会用super(protection)调用Creature的构造函数。在Creature的构造函数中,调用了方法canHaveAsProtection(p),通过动态绑定(bind)获取了Monster中被覆盖的方法。但是,这个被覆盖的版本使用了尚未初始化的最终变量 maxProtection ...我该如何解决这个问题?

最佳答案

几点:

  • 只有 Monster 关心最大值,所以只有它应该知道这个概念
  • 所有生物必须有 > 0 的保护
  • 不要将范围检查推迟到单独的方法
  • 上下界检查不需要在同一个地方
  • 使用装饰器模式解决问题

将所有这些放在一起,您的代码应如下所示:

public class Creature {

private int protection;

protected Creature() {
}

public Creature(int protection) {
setProtection(protection);
}

public void setProtection(int p) {
if (p < 0)
throw new IllegalArgumentException();
this.protection = p;
}
}

public class Monster extends Creature {

private final int maxProtection;

private Monster(int protection) {
this.maxProtection = protection;
setProtection(protection);
}

@Override
public void setProtection(int p) {
if (protection > maxProtection)
throw new IllegalArgumentException();
super.setProtection(p);;
}

public static Monster create(int protection) {
Monster monster = new Monster(protection);
monster.validate();
return monster;
}
}

您还没有显示 validate() 方法终止了什么,但如果它只是用于保护检查,我会删除它和静态工厂方法,并将 Monster 的构造函数公开。

关于Java 在初始化之前引用最终变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16701167/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com