2013-08-18 2 views
1

На данный момент я работаю над игрой, и все идет неплохо. То, что держит меня занятым в данный момент, делает создателя толпы, который порождает мобов в определенной области.Как сделать расширяемый ArrayList?

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

Это мой MobSpawner класс:

public class MobSpawner { 

    protected List<Mob> mobs; 

    protected Level level; 

    protected int timer = 0; 
    protected int spawnTime = 0; 
    protected int maxMobs = 0; 

    public MobSpawner(Level level) { 
     this.level = level; 
    } 

} 

И это мой RoachSpawner класс:

public class RoachSpawner extends MobSpawner { 

    public RoachSpawner(Level level) { 
     super(level); 
     mobs = new ArrayList<Roach>(); // Roach is an extension of Mob 
    } 

} 

Это не сработает, потому что список и ArrayList должны быть одного и того же типа.

Вопрос в том, есть ли у кого-нибудь другие идеи, как это сделать?

Заранее благодарен!

+0

Как и где используется «мобы»? –

+0

Он будет использоваться, чтобы отслеживать, сколько мобов породило породило. –

ответ

3

Я предполагаю, что Roach extends Mob.

Вы можете использовать ArrayList<Mob> для хранения Roach es. Итак:

public RoachSpawner(Level level) { 
    super(level); 
    mobs = new ArrayList<Mob>(); 
} 

И если вы просто использовать ArrayList<Mob> во всех реализациях, вы можете передать его в базу вместо (предполагающей ArrayList всегда контейнер вы хотите - если вы хотите использовать другие List типы см ответ Kwah в и создать список подклассов):

public class MobSpawner { 

    protected final List<Mob> mobs = new ArrayList<Mob>(); 

    ... 

} 

И просто подклассы используют список базы.

Инстанцирование список в базовом классе и делает его final имеет бонусную побочный эффект того, чтобы позволить вам сформулировать следующие инварианты (предполагая, что вы не нарушаете их с отражением или что-нибудь):

  • MobSpawner никогда не будет иметь нулевое значение mobs, а
  • mobs будет ссылаться на один и тот же объект на протяжении всего срока службы MobSpawner.

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

Выполнение этой функции final также предусматривает, что во время компиляции вы случайно не заменяете ее другим списком.

+1

Спасибо за ваш ответ! Вы правы, это просто очень просто, когда я читал это сейчас. Действительно ясное решение: D! Я предполагаю, что большая часть моей проблемы - это моя потребность спать (это 2,42 утра), поэтому, я думаю, мне лучше спать! Еще раз спасибо за вашу идею! –

1

Если вы еще этого не сделали, попробуйте воспользоваться супертипами.

Таким же образом, что вы можете объявить переменную быть List, а затем создать его экземпляр быть ArrayList, попробуйте сказать ваш List содержит Character элементы, а затем заполнить его с конкретными реализациями символов (например, List<Character> конкретизируется в ArrayList<Mob> и ArrayList<Roach>).

public abstract class Character { } 

public class Mob extends Character { } 
public class Roach extends Character { } 



public class Spawner { 
    protected List<? extends Character> characters; 
    protected Level level; 
    protected int timer = 0; 
    protected int spawnTime = 0; 
    protected int maxCharacters = 0; 

    public Spawner(Level level) { 
     this.level = level; 
    } 

} 



public class RoachSpawner extends Spawner { 
    public RoachSpawner(Level level) { 
     super(level); 
     mobs = new ArrayList<Roach>(); 
    } 

} 

public class MobSpawner extends Spawner { 
    public RoachSpawner(Level level) { 
     super(level); 
     mobs = new ArrayList<Mob>(); 
    } 

} 
+0

Ваш код не будет компилироваться. 'ArrayList ' не соответствует 'List '. Измените 'characters' на' List ', и все будет в порядке. –

+0

Ах, прошло какое-то время с тех пор, как я в последний раз погрузился в Java ... Будет ли использование символа интерфейсом альтернативным решением? – kwah

+1

Нет. Базовый класс против интерфейса не влияет на соответствие. Вам все равно придется использовать подстановочный знак. –

Смежные вопросы