Не получить правильные значения для переменных в расширенном классе - PullRequest
0 голосов
/ 11 ноября 2011

Просто делаю быстрое редактирование вверху моего поста.Вопрос заключается в том, расширяю ли я класс, и оба класса имеют одну и ту же переменную, почему расширенный класс получает исходное значение классов.

На этот вопрос дан ответ, но он был бы более рад прочитать дополнительную информацию об этом.Полиморфизм мне не подходит, поэтому мне приходится переучивать этот материал после того, как я не использовал его месяцами.

Так что я пытаюсь запрограммировать игру, и одним из требований является какой-то тип спискаобъекта, который можно сканировать в цикле.Проблема начинается с моего теста ArrayList.У меня есть 3 класса, которые я сделал, чтобы добавить в мой список массивов.Сущности, монстр расширяет сущности, а персонаж расширяет сущности.обратите внимание, что Monster и Character оба расширяют класс Entities.Я решил, что должен создать ArrayList и добавить новые объекты непосредственно в каждый элемент (элемент word обычно используется с массивом, а не в ArrayList?) И использовать запрограммированную мной функцию журнала, чтобы записывать значения объектов в ArrayList.Я сделал цикл for и запустил оба метода: Monster и Character .getHP (), которые они унаследовали от Entities, и результатом стал HP от Entities, а не Monster или Character, если только я не добавил новое значение в классы HP с помощью setHP (int i)Метод также унаследовал сущности.

Так как моей программе требуется большинство классов, а нам нужно только около 99%, я решил сделать тестовый проект, чтобы в основном выполнить описанное выше в меньшей форме, так как я не хочу копировать, вставляя 20 или болееФайлы .java здесь.В любом случае вот мои тестовые классы и результаты.

    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] +»)."##" + [Действие]);»origin всегда класс, а не тот, который должен быть.

Извините, если это не ясно.Если вам нужна дополнительная информация, чтобы помочь мне, я более чем готов ответить.

Ответы [ 3 ]

2 голосов
/ 11 ноября 2011

В основном проблема в том, что вы пытаетесь объявить дополнительные переменные в подклассах, как будто они могут "переопределить" переменную в суперклассе. Переменные не работают таким образом - они не полиморфны.

Если вам нужно присвоить каждому классу различное начальное количество очков жизни, я предлагаю вам создать конструктор protected в Entities (который должен быть переименован, например - AbstractEntity), чтобы принять начальное значение HP (который, вероятно, следует переименовать в hitPoints). Тогда у каждого подкласса будет открытый конструктор для вызова суперконструктора с соответствующим значением.

Например:

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

Теперь это просто вопрос изменения начального состояния. Если вы хотите, чтобы разные сущности по-разному вели себя , вы должны переопределить методы абстрактного класса в подклассах.

0 голосов
/ 11 ноября 2011

Если я правильно понимаю, проблема в следующем:

Вы объявили атрибут HP как закрытый в классе Entities и объявили новую (!) Переменную в подклассе (см. Другие ответы).

Вы можете разрешить поведение, задав HP конструкторам, e. г.

class Entitites {
  private int HP;

  public Entities(int hp) {
    this.HP = hp;
  }
}

class Monster extends Entities {
  public Monster() {
    super(4);
  }
}
0 голосов
/ 11 ноября 2011

Я полагаю, что ваша проблема в определении области HP, что Entities* доступно из вашего getHP, но ваши HP в Character и Monster - это разные переменные с одинаковым именем. Кроме того, пометка HP как private означает, что подклассы не могут получить доступ к этой переменной - я думаю, что у вас есть protected.

Каково, вероятно, правильное решение, чтобы избавиться от HP в Monster and Character, защитить HP в Entities и установить HP по умолчанию в конструкторе по умолчанию для Monster and Character.

* Это хороший стиль, чтобы называть ваши объекты в единственном числе, так что это лучше назвать как Entity.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...