Как получить доступ к имени вещей в моем списке массивов, который является списком массивов моего типа интерфейса?

Название многословное и, возможно, запутанное, но я не уверен, как сделать его лучше... Я хочу иметь доступ к значениям в моем списке массивов и распечатывать их.

У меня есть интерфейс под названием ThingBagInterface. Этот ThingBagInterface имеет только один метод и выглядит следующим образом:

interface ThingBagInterface {
    public String getType();
}

Теперь у меня есть класс под названием ThingBag, это сумка, в которой хранится куча разных вещей, таких как существа, здания и т. д.

В моем классе ThingBag я инициализировал все свои существа следующим образом:

public void initCreatures(){
     waterSnake = new Creature("Water Snake", Terrain.SWAMP, false, false, false, false, 1, 0);
    etc...
}

а затем у меня есть функция populateBag(), которая выглядит так:

public void populateBag(){
    initCreatures();

    bag.add(bears);
}

Мое определение списка массивов находится в ThingBag и выглядит так:

ArrayList<ThingBagInterface> bag = new ArrayList<ThingBagInterface>();

Конструктор My Creature выглядит так:

    public Creature(String n, Terrain startTerrain, boolean flying, boolean magic, boolean charge, boolean ranged, int combat, int o){
        name = n;
        flyingCreature = flying;
        magicCreature = magic;
        canCharge = charge;
        rangedCombat = ranged;
        combatValue = combat;
        owned = o;
    }

Я хочу распечатать имя медведя.

Итак, в основном я делаю это:

ThingBag tb = new ThingBag();
tb.populateBag();
for(int i= 0; i<tb.bag.size(); i++){
    System.out.println(i+". "+tb.bag.get(i));
}

Почему я не могу получить доступ к имени в моей сумке? Если бы я не использовал интерфейс, я мог бы сказать:

System.out.println(i+". "+tb.bag.get(i).name) 

Но я не могу сейчас. Любые идеи о том, как я могу получить доступ к этому значению? Теперь я могу получить доступ только к адресам памяти...


person Sarah    schedule 28.01.2014    source источник


Ответы (3)


Ваша переменная bag объявлена ​​как

ArrayList<ThingBagInterface> bag ...

Концептуально это означает, что он содержит не менее ThingBagInterface объектов. Он может содержать любой тип ThingBagInterface, но он должен быть как минимум ThingBagInterface.

Это также означает, что компилятор может гарантировать только то, что он содержит ThingBagInterface, и поэтому вы можете взаимодействовать с его элементами только как с ThingBagInterface экземплярами.

name не является полем, существующим в типе ThingBagInterface, оно существует в Creature.

Вы можете либо преобразовать возвращаемое значение bag.get(i), либо объявить метод getName() ThingBagInterface, реализовать его в подтипах и вызвать в своем цикле.

person Sotirios Delimanolis    schedule 28.01.2014
comment
Спасибо, это мой первый раз, когда я пытаюсь использовать интерфейс, поэтому я собираюсь сделать много глупых ошибок, пока не разберусь с этим. Еще раз спасибо. - person Sarah; 28.01.2014
comment
Обратите внимание, что если вы собираетесь приводить элементы к Creature, нет особых причин вообще иметь ThingBagInterface. ArrayList<Creature> будет работать лучше. - person user2357112 supports Monica; 28.01.2014
comment
@Sarah Обратите внимание на то, что только что сказал пользователь 2357112. У вас много ThingBagInterface? У них у всех есть name? Рассмотрите возможность создания базового класса для всех из них. - person Sotirios Delimanolis; 28.01.2014
comment
У них у всех есть имя. Я не уверен, действительно ли я хочу интерфейс или наследование. У меня был список массивов существ, но мне нужно было изменить его, потому что мой список массивов должен содержать несколько разных типов вещей. У всех у них есть имя, так что, может быть, мне следует пойти именно туда, но имя — это все, что у них общего. - person Sarah; 28.01.2014

Вам нужно разработать интерфейс ThingBagInterface более разумно. Является ли наличие имени требованием? Если это так, интерфейсу нужен способ доступа к имени объекта. (Это должен быть метод, так как интерфейсы не могут задавать поля.) Пока мы этим занимаемся, было бы неплохо выбрать более информативное имя, чем ThingBagInterface.

person user2357112 supports Monica    schedule 28.01.2014
comment
это интерфейс для сумки, в которой хранятся вещи, которые являются названиями игровых элементов для настольной игры, которую я пытаюсь реализовать, так что это довольно информативно, но я понимаю, что вы пытаетесь сказать, так что спасибо - person Sarah; 28.01.2014
comment
@Sarah: Имя не дает никакой информации о том, как оно связано с ThingBag. Похоже, что ThingBag должен реализовать это, а не вещи, содержащиеся в сумке. Представьте, если бы интерфейс для пассажиров в машине назывался CarInterface. - person user2357112 supports Monica; 28.01.2014

Может быть, сделать такой бросок System.out.println(i+". "+(((Creature)tb.bag.)get(i));

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

Надеюсь, это поможет.

person user_loser    schedule 28.01.2014