2013-09-24 4 views
0

Я работал над небольшой системой инвентаризации, чтобы практиковать мое программирование OO. Я использую Java 7 в Netbeans.Проектирование системы инвентаризации предметов для игры и с проблемами

У игрока будет инвентарь (ArrayList базового класса предметов), все созданные объекты будут дочерними элементами этого базового класса предметов.

Нет элементов, которые должны быть типа BaseItem, все они будут простираться от этого, так что, насколько мне известно, класс BaseItem должен быть абстрактным?

public abstract class BaseItem { 
    protected GoldValue itemValue; 
    protected String itemName; 

    //accessors and mutators down here 
} 

типов элементов для детей также будут иметь разные свойства, которые я собирался реализовать, как интерфейсы, такие как стекируемые, расходная и т.д.

Интерфейс выглядит что-то вроде этого

public interface Stackable { 

    public void stack (StackableItem bi1); 

} 

Как вы можете видеть, я ссылаюсь на StackableItem здесь, это один из дочерних элементов BaseItem, который также является абстрактным, а конкретные элементы будут построены.

public abstract class StackableItem extends BaseItem implements Stackable{ 

    protected int quantity; 
    protected int maxStacks; 

    @Override 
    public void stack (StackableItem si) 
    { 
     if(this.getQuantity() + si.getQuantity() < maxStacks){ 
      this.setQuantity(this.getQuantity()+si.getQuantity()); 
      si.setQuantity(0); 
     } 
     else if(this.getQuantity() + si.getQuantity() > maxStacks){ 
      int diff = maxStacks - this.getQuantity(); 
      this.setQuantity(this.getQuantity() + diff); 
      si.setQuantity(si.getQuantity() - diff); 
     } 
    } 
} 

и вот пример конкретного пункта:

public class StackableItemExample extends StackableItem{ 

    public StackableItemExample()throws GoldException 
    { 
     this(new GoldValue(0,0,0), "unnamed", 1); 
    } 
    public StackableItemExample(GoldValue gv, String name, int quan) throws GoldException 
    { 
     this.itemValue = gv; 
     this.itemName = name; 
     this.quantity = quan; 
     this.maxStacks = 10; 
     this.itemValue.setGoldValue(gv.getGold()*quan, gv.getSilver()*quan, gv.getCopper()*quan); 
    } 


} 

Мои Inventory, будучи ArrayList из BaseItem объектов, разрешено иметь StackableItemExample объект не вставлен в него без проблем. Проблема в том, что моя система инвентаризации не может сказать BaseItem.stack(), поскольку родитель не знает об этом методе.

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

ответ

2

Ни один элемент не должен быть типа BaseItem, все они будут простираться от этого, так что, насколько мне известно, класс BaseItem должен быть абстрактным?

Звучит хорошо для меня


Если вы хотите BaseItem.stack() работать, вы могли бы сделать, по крайней мере, две вещи:

  • Move stack() в свой базовый класс, и дать ему реализацию по умолчанию ничего не делать. Затем переопределите это в своем классе StackableItem, или
  • Используйте instanceof, чтобы узнать, является ли BaseItem StackableItem, затем отбросит его на StackableItem и оттуда.

Второй подход будет выглядеть так:

BaseItem item = YourList.get(i); 
if(item instanceof StackableItem){ 
    StackableItem stackable = (StackableItem)item; 
    stackable.stack() /* Now works without issue */ 
} 
+0

Я дам ему попробовать, но есть возможность что некоторые данные будут потеряны при кастинге? То, что я прошу, имеет элемент, который все еще имеет значения класса StackableItem, но просто не отображается при использовании элемента. или пункт. ()? Если это так, то это работает отлично! – EyeOfTheHawks

+0

Да, это точно, как это работает (и нет, данные не будут потеряны). Вы не теряете дополнительную информацию об объекте - это тип времени выполнения, все, что вы его создали. Вы просто не можете получить доступ к этим членам/методам, если только вы не перенесли их в соответствующий подкласс. – jedwards

+0

Удивительно, это должно работать отлично. Любые предупреждения с этим так? Тип, бросающий объект, кажется очень рискованным, но до тех пор, пока мы используем instanceof, мы должны быть в порядке? – EyeOfTheHawks

0

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

+0

К сожалению, этот тип реализации, вероятно, не будет работать с другими свойствами элемента, например, съедобные – EyeOfTheHawks

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