java - 没有获得扩展类中变量的正确值

标签 java class inheritance polymorphism extend

只是在我的帖子顶部进行了快速编辑。 问题是,如果我扩展一个类并且两个类具有相同的变量,为什么扩展类会获取原始类值。

此问题已得到解答,但我非常乐意阅读有关此问题的更多信息。 多态性不是我的强项,所以几个月没有使用它后我不得不重新学习这些东西。

所以我正在尝试编写一个游戏,其中一个要求是某种类型的可以循环扫描的对象列表。问题是从我对 ArrayList 的测试开始的。我有 3 个类要添加到我的数组列表中。实体,怪物扩展实体,角色扩展实体。请注意,怪物和角色都扩展了实体类。 我决定创建 ArrayList 并直接向每个元素添加新对象(元素这个词通常与数组一起使用,而不是 ArrayList 正确吗?),并使用我编程的日志函数来记下 ArrayList 中对象的值。 我做了一个for循环并运行了它们从实体继承的Monster和Character .getHP()方法,结果是来自实体的HP而不是Monster或Character,除非我使用setHP(int i)向HP类添加了新值方法也继承了Entity。

由于我的程序需要大部分类,而我们只需要大约 99%,因此我决定创建一个测试项目,基本上以较小的形式执行上述操作,因为我不想复制粘贴 20 个或更多 .java 文件这里。无论如何,这是我的测试类(class)和结果。

    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 {

}

这是我对上面这些文件的结果。我应该把 HP 放在左边的数字旁边,但你明白了。

[Character@67f1fba0, Monster@3fbefab0, NPC@133c5982]
1 is Character@67f1fba0
1 is Monster@3fbefab0
1 is NPC@133c5982
11 is Character@67f1fba0
12 is Monster@3fbefab0
13 is NPC@133c5982

我的原始 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);
        }
    }
}

这是我的结果。

[Area Map]##[Testing arrayList]
[Area Map]##[ent 1 has [Character@2bd1e730, Monster@61a116c9] in it]
[Area Map]##[ArrayList 0 i=0]
[Area Map]##[ArrayList 0 i=1]
[Area Map]##[ArrayList 10 i=0]
[Area Map]##[ArrayList 11 i=1]

请注意,“Log”是我制作的一个类,方法是“static Logging(String origin, String Action){System.out.println([origin]+"##"+[Action]);” origin 始终是类,但并非必须如此。

抱歉,如果不清楚。如果您需要更多信息来帮助我,我非常乐意回答。

最佳答案

基本上,问题在于您试图在子类中声明额外的变量,就好像它们可以“覆盖”父类(super class)中的变量一样。变量不是这样工作的——它们不是多态的。

如果您需要为每个类提供不同的起始生命值,我建议您在 Entities 中创建一个 protected 构造函数(应该重命名,顺便说一句 - 例如AbstractEntity) 来获取 HP 的初始值(可能应该重命名为 hitPoints)。然后每个子类都会有一个公共(public)构造函数来使用适当的值调用 super 构造函数。

例如:

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);
    }
}

现在只需更改初始状态即可。如果您希望不同的实体有不同的行为,您应该重写子类中的抽象类方法。

关于java - 没有获得扩展类中变量的正确值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8094105/

相关文章:

java - 如何纠正这个: Content is not allowed in prolog

c++ - 为什么我不能对具有继承的结构使用列表初始化?

html - 无法获取要使用的类

c++ - 在我的类 C++ 中创建一个对象

javascript - 为什么 Javascript 默认不支持继承?

c# - Java 继承与 C# 继承

java - 用于修复格式错误的 URI 的 Scala 或 Java 库

java - 在 Swing 的 EDT 中实现线程?

C++使用基类指针访问派生类方法

java - ResultSet 关闭后占用 RAM