Java 获得超级';属性值而不是实际对象
我有以下资料:Java 获得超级';属性值而不是实际对象,java,inheritance,Java,Inheritance,我有以下资料: 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 d
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)
}
工程师类已重写此方法:
@Override
public void receiveDamage(Attacker entity) {
if (entity instanceof Zombie) {
int damagePoints = ((Zombie) entity).getDamagePoints();
this.setHealthPoints(this.getHealthPoints() - damagePoints);
}
}
现在我有一个实例化的工程师和一个僵尸。
当我执行僵尸攻击(工程师)时,我在工程师类的receiveDamage()
中放置了一个断点,我得到的损伤点是0
你知道为什么会这样吗?这是因为我复制了属性damagePoints
?如果是这样的话,我怎么能让一个僵尸拥有40个伤害点而不在所有构造器中重复this.damagePoints=40
您在僵尸
中声明了损坏点
,希望实体
中的获取损坏点()
能够在僵尸
中获取新值,但正如您所看到的,它没有。在Java中,多态性适用于方法调用,但不适用于变量。Entity
中的damagePoints
变量是getDamagePoints()
方法范围内的变量,因此从Entity
的damagePoints
变量返回0
要获取Zombie
中返回的40
,不需要重新声明另一个同名变量,将damagePoints
变量隐藏在实体中,但可以覆盖Zombie
中的getDamagePoints()
方法。你不需要一个变量,更不用说一个同名的变量(除非你计划在游戏中改变数量)。在僵尸中
:
@Override
public int getDamagePoints() {
return 40;
}
您甚至可能希望您的getDamagePoints()
方法是Entity
中的abstract
,强制子类实现该方法。这意味着实体
中不需要变量损坏点
public abstract int getDamagePoints();
这是因为当调用getDamagePoints
时,它返回的是抽象类实体的damagePoints值,而不是扩展它的类。通过将实体的getDamagePoints方法抽象,并为每个扩展类提供一个实现来修复此问题。僵尸似乎有多个构造函数,所有构造函数都需要初始化damagePoints以避免重复代码,包括可能重复的getDamagePoints方法
解决方案是使用“this”将构造函数连接在一起。例如,如果一个构造函数获取其他每个构造函数的参数超集,则在其中执行实际工作:
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 */
}
如果没有公共超集构造函数,您仍然可以使用“this”来完成公共工作。您可能需要使用特殊的专用构造函数:
private Zombie(boolean special) {
damagePoints = 40;
}
public Zombie() {
this(true);
/* Rest of the constructor */
}
这不是我希望的答案,因为我认为继承是为了避免重复相同的代码。很遗憾,我认为PHP的工作方式与我期望的(IIRC)相同