我有以下内容:
Public Abstract class Entity
protected int damagePoints = 0;
public getDamagePoints() {
return this.damagePoints;
}
Public abstract class IA extends Entity
Public class Zombie extends IA implements Attacker {
protected int damagePoints = 40;
}
Public class Engineer extends Entity implements DamageReceiver;
Public interface Attacker {
public attack(Entity entity);
}
Public interface DamageReceiver {
public receiveDamage(Attacker entity)
}
Engineer类重写了这个方法:
@Override
public void receiveDamage(Attacker entity) {
if (entity instanceof Zombie) {
int damagePoints = ((Zombie) entity).getDamagePoints();
this.setHealthPoints(this.getHealthPoints() - damagePoints);
}
}
现在我有一个工程师实例化,还有一个Zombie。
当我Zombie.attack(engineer)
时,我在工程师班的receiveDamage()
中设置了一个断点,我认为damagePoints
是0
。
为什么会发生这种情况的任何线索?这是因为我复制了属性damagePoints
吗?如果是这样,我如何让Zombie拥有40个伤害点,而不是在所有构造函数中重复this.damagePoints = 40
?
答案 0 :(得分:2)
您在damagePoints
中重新声明了Zombie
,希望getDamagePoints()
中的Entity
能够在Zombie
中获取新值,但就像您一样看来,它没有。在Java中,多态性与方法调用一起使用,但不与变量一起使用。 damagePoints
中的Entity
变量是getDamagePoints()
方法的范围变量,因此从0
的{{1}}变量返回Entity
要在damagePoints
中返回40
,您无需重新声明另一个同名变量,隐藏 Zombie
变量damagePoints
,但您可以覆盖Entity
中的getDamagePoints()
方法。你不需要一个变量,更不用说同名变量了(除非你计划在游戏中改变数量)。在Zombie
:
Zombie
您甚至可能希望@Override
public int getDamagePoints() {
return 40;
}
方法在getDamagePoints()
中为abstract
,从而强制子类实现该方法。这意味着Entity
中不需要变量damagePoints
。
Entity
答案 1 :(得分:0)
这种情况正在发生,因为当你调用getDamagePoints
时,它会返回抽象类Entity
的damagePoints值,而不是已经扩展它的类。通过使Entity
的getDamagePoints方法为abstract来解决此问题,并为每个扩展类提供实现。
答案 2 :(得分:0)
看来Zombie有多个构造函数,所有构造函数都需要初始化damagePoints以避免重复代码,包括可能重复方法getDamagePoints。
解决方案是使用"这个"将建设者联系在一起。例如,如果一个构造函数为每个其他构造函数获取参数的超集,则执行其中的实际工作:
public Zombie(/* some subset of parameters */){
this(/* full set of parameters with defaults filled in */);
}
public Zombie(/* full set of parameters */){
damagePoints = 40;
/* rest of initialization */
}
如果没有常见的超集构造函数,你仍然可以使用"这个"做共同的工作。您可能需要使用特殊的私有构造函数:
private Zombie(boolean special) {
damagePoints = 40;
}
public Zombie() {
this(true);
/* Rest of the constructor */
}