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 ...
}