Java 未获取扩展类中变量的正确值
只是在我的帖子顶部做一个快速编辑。 问题是,如果我扩展了一个类,并且两个类都有相同的变量,那么为什么扩展类会得到原始类的值 这一点已经得到了回答,但我们非常乐意阅读更多关于这一点的信息。 多态性不是我的强项,所以在几个月没有使用它之后,我不得不重新学习它 所以我试图编写一个游戏,其中一个要求是某种类型的对象列表,可以在循环中扫描。问题从我对ArrayList的测试开始。我有3个类要添加到数组列表中。实体,怪物扩展实体,角色扩展实体。注意怪物和角色都扩展了实体类。 我决定制作ArrayList,并将新对象直接添加到每个元素中(单词element通常与array not ArrayList correct一起使用),并使用我编程的日志函数记录ArrayList中对象的值。 我做了一个for循环,并运行了Monster和Character.getHP()方法,它们从实体继承而来,结果是实体的HP而不是Monster或Character,除非我使用setHP(int I)方法向类HP添加了一个新值,该方法也继承了实体 因为我的程序需要大部分类,我们只需要99%的类,所以我决定做一个测试项目,基本上以较小的形式完成上述工作,因为我不想复制粘贴20个或更多的.java文件。不管怎样,这是我的测试课程和结果Java 未获取扩展类中变量的正确值,java,class,inheritance,polymorphism,extend,Java,Class,Inheritance,Polymorphism,Extend,只是在我的帖子顶部做一个快速编辑。 问题是,如果我扩展了一个类,并且两个类都有相同的变量,那么为什么扩展类会得到原始类的值 这一点已经得到了回答,但我们非常乐意阅读更多关于这一点的信息。 多态性不是我的强项,所以在几个月没有使用它之后,我不得不重新学习它 所以我试图编写一个游戏,其中一个要求是某种类型的对象列表,可以在循环中扫描。问题从我对ArrayList的测试开始。我有3个类要添加到数组列表中。实体,怪物扩展实体,角色扩展实体。注意怪物和角色都扩展了实体类。 我决定制作ArrayList,并
import java.util.ArrayList;
// class to test interactions between Extended classes
public class testHP {
ArrayList<Entities> ent = new ArrayList<Entities>();
public static void main(String[] args) {
///make reference varaible so i don't have to make test() and ent static.
testHP hp = new testHP();
hp.test();
}
void test(){
/// the 3 classes to the arraylist. I could of made a reference variable but didn't.
this.ent.add(new Character());
this.ent.add(new Monster());
this.ent.add(new NPC());
///prints out whats in the array list so i know that i have the correct objects.
System.out.println(this.ent);
/// this prints out { ent(i) HP "is" i } to tell which class is being called and it's HP at this point.
for(int i=0; i<ent.size();i=i+1) {System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
/// this adds i plus 10 then does the same as the last for loop.
for(int i=0; i<ent.size();i=i+1) {
this.ent.get(i).gainHP(i+10);
System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
}
}
abstract public class Entities {
private int HP = 1;
int getHP(){
return HP;
}
void gainHP(int hp){
HP = this.HP + hp;
}
}
///Character is to show what happens when i change the value and make it static.
public class Character extends Entities {
private static int HP = 4;
}
///monster is to show a changed variable from the super which is entities.
public class Monster extends Entities {
private int HP = 4;
}
/// NPC is a class that just to have variables from entities class that aren't edited or made static.
public class NPC extends Entities {
}
原始ArrayList的测试类如下所示
import java.util.ArrayList;
public class AreaMap extends Map {
String CLASS = "Area Map";///log requires.
ArrayList<Entities> ent = new ArrayList<Entities>();
AreaMap(){
Log.Logging(CLASS,"Testing arrayList");
//random text added to the array.
ent.add(new Character());
ent.add(new Monster());
Log.Logging(CLASS, "ent 1 has " +ent+ " in it");
for(int i=0; i < ent.size();i = i+1){
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
for(int i=0; i < ent.size();i = i+1){
this.ent.get(i).setHP(10+i);
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
}
}
请注意,“Log”是我创建的一个类,方法是“静态日志记录(字符串原点,字符串操作){System.out.println([origin]+”##“+[Action])”
起源始终是类,而不是它必须是类
很抱歉,这还不清楚。如果您需要更多信息来帮助我,我非常愿意回答。基本上,问题是您试图在子类中声明额外的变量,好像它们可以“覆盖”超类中的变量。变量不是这样工作的-它们不是多态的 如果您需要为每个类指定不同的起始生命点数,我建议您在
实体中创建一个受保护的构造函数(应该重命名,顺便说一句-例如抽象实体
),以获取HP
的初始值(可能应该重命名生命点
)。然后每个子类都会有一个公共构造函数来调用具有适当值的超构造函数
例如:
public abstract class AbstractEntity {
private int hitPoints;
protected AbstractEntity(int initialHitPoints) {
this.hitPoints = initialHitPoints;
}
public int getHitPoints(){
return hitPoints
}
void gainHitPoints(int amount) {
hitPoints += amount;
}
}
public class Monster extends AbstractEntity {
public Monster() {
// Every monster starts off with 4 hit points
super(4);
}
}
现在,这只是更改初始状态的问题。如果您希望不同实体的行为不同,则应该重写子类中的抽象类方法。我相信您的问题在于范围。可以从getHP
访问实体的HP
*,但是您的HP
在Character
和Monster
是恰好同名的不同变量。此外,将HP
标记为private
意味着子类无法访问该变量-我认为您已受保护
什么可能是正确的解决方案来摆脱怪物和角色中的HP,使实体中的HP受到保护,并在怪物和角色的默认构造函数中设置默认HP
*用单数命名对象是一种很好的方式,因此最好将其命名为实体
如果我理解正确,问题如下:
您在类实体中将属性HP
声明为private,并在子类中声明了一个新的(!)变量(请参见其他答案)
您可以通过构造函数设置HP来解决该行为,例如
class Entitites {
private int HP;
public Entities(int hp) {
this.HP = hp;
}
}
class Monster extends Entities {
public Monster() {
super(4);
}
}
抱歉,JayCD我可能浏览了你的文章太快了,但是里面有什么问题吗?(除了这个问题:单词element通常与array not ArrayList correct一起使用?)抱歉,它似乎解释了发生的事情,但没有真正提出问题。我想知道我是否扩展了一个类,为什么实例变量与我的超级类中的变量相同。如果我没有过度使用,我会想到这一点,但我是。下面的John说我不能这样做,这似乎支持了我使用这些类的经验。太好了。我知道该怎么做以及如何在功能中避免此错误。
public abstract class AbstractEntity {
private int hitPoints;
protected AbstractEntity(int initialHitPoints) {
this.hitPoints = initialHitPoints;
}
public int getHitPoints(){
return hitPoints
}
void gainHitPoints(int amount) {
hitPoints += amount;
}
}
public class Monster extends AbstractEntity {
public Monster() {
// Every monster starts off with 4 hit points
super(4);
}
}
class Entitites {
private int HP;
public Entities(int hp) {
this.HP = hp;
}
}
class Monster extends Entities {
public Monster() {
super(4);
}
}