Можно ли называть подкласс типом своего суперкласса?

Я делаю игру в школе. У меня есть оружие, которое является подклассом предметов. И у меня есть поле currentWeapon в моем классе под названием BattleGround. И у меня есть метод поиска и перебора всех предметов в моем «рюкзаке». Я надеялся также использовать это для оружия, так как они тоже являются предметами.

Я надеялся, что объект класса Weapon также можно назвать элементом. Но я просто не знаю. Нужен ли мне новый метод для перебора Weapon? И Weapon, и Item должны храниться в одном рюкзаке.

Если я сохраню поле currentWeapon как Weapon, я не смогу использовать метод и, возможно, не буду хранить Weapon в Hashmap из String и Item. Если я сохраню его как Item, я не смогу использовать методы класса Weapon. Спасибо.


person Joakim Vindenes    schedule 04.04.2013    source источник
comment
Думаю, пример облегчит понимание.   -  person Kai    schedule 04.04.2013
comment
Да, одно из определений подкласса состоит в том, что его можно использовать везде, где требуется экземпляр его суперкласса. Итак, в вашем случае, если Weapon extends Item и есть код, который принимает Item, он также примет Weapon.   -  person miorel    schedule 04.04.2013
comment
Да, я понимаю, но это довольно простой вопрос, не так ли? Можно ли рассматривать оружие как предметы? Можно ли рассматривать подкласс как тип суперкласса? Можно ли хранить объекты подкласса оружия в HashMap‹String, Item›?   -  person Joakim Vindenes    schedule 04.04.2013
comment
@JoakimVindenes Да на все 3 вопроса. Найдите Polymorphism.   -  person Tushar    schedule 04.04.2013
comment
Если Weapon является подклассом Item, это совершенно нормально.   -  person Tom Walters    schedule 04.04.2013
comment
Спасибо, Миорел, это то, что я хотел услышать. Теперь позвольте мне показать вам код. В моей игре мой персонаж может ввести выбор оружия. Затем он перебирает все предметы в рюкзаке, чтобы увидеть, существует ли он, а затем сохраняет это оружие в поле currentWeapon (которое относится к типу оружия). общедоступный элемент findItem (строка itemName) { return backpack.get (itemName); } Но когда я пытаюсь сохранить то, что я нашел, в поле currentWeapon (теперь я пытаюсь сохранить ITEM в поле WEAPON, и я думаю, что это неправильный способ), я получаю сообщение об ошибке Несовместимые типы, найденный элемент но ожидаемое оружие. Как?   -  person Joakim Vindenes    schedule 04.04.2013
comment
@JoakimVindenes Если на этот вопрос был дан ответ, пожалуйста, создайте новый вопрос, если у вас есть дополнительные мысли.   -  person maba    schedule 04.04.2013


Ответы (1)


Если Weapon является подклассом Item, то вы можете без проблем хранить Weapon в коллекции объектов Item. Возможно, вам нужно выучить оператор instanceof:

List<Item> items = new ArrayList<>();

// add some items to the list

for (Item item : items) {
  if (item instanceof Weapon) {
    Weapon weapon = (Weapon) item; // cast the item to a weapon
    weapon.someWeaponMethod();
  }
}

Если вы используете instanceof, вы можете определить, действительно ли ваш Item является Weapon.

person Duncan Jones    schedule 04.04.2013
comment
В целом другое замечание: instanceOf проверки не должны использоваться часто! Иногда есть доступное решение, и использование instanceOf указывает на запах дизайна. - person Narendra Pathai; 04.04.2013
comment
@NarendraPathai Я не думаю, что вы можете сделать такое широкое заявление. Как и в случае с любой программной идиомой, вам действительно нужно увидеть контекст, чтобы понять, правильный ли это выбор. - person Duncan Jones; 04.04.2013
comment
Я думаю, стоит упомянуть, что вы применяете предмет к оружию. Это позволяет нам получать доступ к методам и полям, определенным в Weapon, а не только к Item. - person Cedric Reichenbach; 04.04.2013
comment
@CedricReichenbach Хороший вопрос - я сделал пример кода более понятным. - person Duncan Jones; 04.04.2013
comment
@NarendraPathai Вы правы, это похоже на запах дизайна, но проблема в другом. Я думаю, что оружие не должно храниться вместе со всеми другими предметами, но в таком случае я думаю, что использование instanceof чище, чем, например. ввести какое-то свойство itemType или что-то в этом роде. - person Cedric Reichenbach; 04.04.2013
comment
Верно, но я не говорю, что ваше решение неверно. Просто нужно принять во внимание, что этого не должно происходить. - person Narendra Pathai; 04.04.2013