2016-09-27 4 views
0

В настоящее время я создаю игру в java (пошаговая RPG) и сталкиваюсь с проблемой в пользовательском интерфейсе инвентаризации. Возможно, моя проблема хорошо известна или имеет простое решение, но никогда не было никакой подготовки, я все равно задаю вопрос.проверка типа ссылки в generics java

При отображении инвентаря после выбора элемента я проверяю, реализует ли этот элемент интерфейс SpecificItemWorker, то есть действует на конкретный GameObject, который должен быть передан его методу takeAction(). Выбирая тот объект, который должен быть передан, я показываю все возможные объекты-кандидаты для выбора пользователем. Например, предположим, что пользователь выбирает UpgradeParchment, который действует на любой объект, реализующий интерфейс Upgradable. Здесь я инициирую ItemSelector, который отображает все элементы в инвентаре, который реализует Upgradable. Однако с другим классом интерфейс, который объект должен реализовать для того, чтобы быть потенциальным кандидатом, будет отличаться. (Обратите внимание, что некоторые объекты воздействуют на игровую среду, а не на определенный объект, но мы не рассматриваем этот случай здесь.). Теперь вместо жесткого кодирования возможных интерфейсов в операторе switch case я хочу, чтобы он был dynamic.I пытался использовать generics, но он не позволяет проверить, является ли объект instanceof параметра Type. Следующий код дает ошибку компиляции:

package ui; 

import objects.Collectable; 

public class ItemSelector<T> { 
    public void test(Collectable ob) { 
     if (ob instanceof T) {// compile error 
      // do work 
     } 
    } 
} 

Кто-нибудь знает, как это может быть достигнуто Спасибо за любую помощь.

Ищет быстрый ответ, Спасибо.

EDIT: Параметр в методе testAction() будет типа Collectable как в моем классе инвентаризации, есть только список Collectable objects.Similarly, в моем методе испытаний, я обновил types.Although его это незначительные изменения, извините за любые неудобства. Collectable также является интерфейсом.

ответ

1

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

public class ItemSelector<T> { 
    private final Class<T> clazz; 
    public ItemSelector(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    public void test(GameObject ob) { 
     if (clazz.isInstance(ob)) {// use token to check type 
      // do work 
     } 
    } 
} 

Это требует объект класса, который будет передан в конструктор, как правило, передав литерал класса , например MyClass.class

0

Существует способ проверить тип с помощью class.getTypeName().

Я предполагаю, что SpecificItemWorker является игровым объектом, как показано в коде.

package stackoverflow.question39718130; 

public class SpecificItemWorker extends GameObject { 
} 

package stackoverflow.question39718130; 

public class ItemSelector<T> { 

    private T t; 

    public ItemSelector(final T t) { 
     this.t = t; 
    } 

    public T getT() { 
     return t; 
    } 

    public void test(final GameObject ob) { 
     /*if (ob instanceof T) {// compile error 
      // do work 
     }*/ 

     if (t.getClass().getTypeName() == ob.getClass().getTypeName()) { 
      System.out.println("Grab item."); 
     } else { 
      System.err.println("No item found."); 
     } 
    } 
} 

Существует тестовый пример, чтобы передать GameObject.

package stackoverflow.question39718130; 

public class GameObjectTest { 

    public static void main(final String[] args) { 
     specificItemWorkerTest(); 
    } 

    public static void specificItemWorkerTest() { 
     final GameObject specificItemWorker = new SpecificItemWorker(); 

     final ItemSelector<GameObject> selector = new ItemSelector<>(specificItemWorker); 
     selector.test(specificItemWorker); 
    } 
} 

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

+1

Метод 'class.getTypeName()' возвращает информацию о типе класса. Но он не может использоваться для передачи теста отношения IS-A. Кроме того, 'SpecificItemWorker' является интерфейсом.Он используется для определения того, должен ли объект, который пользователь выбирает использовать, требует другого объекта «Collectable» для работы. –

+0

Это неверно на нескольких уровнях, но особенно с помощью '==' для сравнения строк, которые никогда не будут истинными – Bohemian

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