Java intanceof false, если есть родитель

Я создаю какую-то систему достижений, у меня есть класс KillXEnemies, а затем я наследую его с помощью таких классов, как KillXEnemiesWeapon (враги, убитые определенным оружием). И когда вы убиваете врага, я зацикливаюсь на объектах достижения и добавляю, что враг был убит:

if(object instanceof KillXEnemies)
    ((KillXEnemies)object).addEnemyKilled();

Но затем отслеживается и KillXEnemiesWeapon, поскольку он наследуется от KillXEnemies. Я знаю одно решение:

if(object instanceof KillXEnemies && !(object instanceof KillXEnemiesWeapon))
    ((KillXEnemies)object).addEnemyKilled();

Но я собираюсь получить довольно много классов, которые наследуются от KillXEnemies, и кажется, что это плохое решение, например 20!(Object instanceof (---))

Поэтому мне интересно, есть ли более простой способ проверить, является ли объект только KillXEnemies, а не KillXEnemiesWeapon

5 ответов

Решение

Ты можешь использовать Object#getClass чтобы получить фактический класс объекта, а затем сравнить его с KillXEnemies.class,

if (object.getClass().equals(KillXEnemies.class))

Это будет true из object это KillXEnemies но не если object является экземпляром его подкласса.

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

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

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

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

Как насчет добавления флага, например, parentClass, который имеет значение true для родительского класса и false для всех подклассов? Таким образом, ваше условие было бы, если (объект instanceof объекта KillXEnemies && ((KillXEnemies)).isParentClass()) {

Я бы сделал это с переопределенными методами. Публичный метод boolean doesKillEnemies() в KillXEnemies, Обеспечьте реализацию по умолчанию и wverride в зависимости от ситуации, чтобы она возвращала true в тех классах, чьи объекты убивают врагов, и false во всех других подклассах.

Затем тест становится:

if(object instanceof KillXEnemies && ((KillXEnemies)object).doesKillEnemies())
    ((KillXEnemies)object).addEnemyKilled();

Используйте беднягу RTTI. Сделайте так, чтобы каждый ваш конкретный класс реализовывал базовый метод getObjType(). Это может закончиться чище и быстрее, чем лес instanceof.

switch(obj.getObjType()){
   case KillXEnemies.TYPE_ID:
       doSomething((KillXEnemies)obj);
   break; 
  case KillXEnemiesWeapon.TYPE_ID:
       doSomething((KillXEnemiesWeapon)obj);
   break;
   //and so on ...
}
Другие вопросы по тегам