Java HashMap с объектом в качестве значения вместе со всем, что его расширяет?

#java #hashmap

#java #hashmap

Вопрос:

У меня есть HashMap, который принимает строку в качестве ключа и объект в качестве значения, в данном случае класс, который я создал, называется ItemBuilder . Я могу поместить другой класс, который расширяет его как значение, но я не могу использовать ни один из методов, которые есть у класса. Почему это так?

 HashMap<String, ItemBuilder> registry = new HashMap<String, ItemBuilder>();
registry.put("ZEUS_BOLT", new ZeusBolt());
registry.get("ZEUS_BOLT").testLog();
 

Ответ №1:

Когда вы проверите документацию для Map, вы увидите, что Map<K, V> метод for , отображается как V get(Object key) . Это означает, что get возвращает объект типа, указанного в объявлении переменной, в вашем случае ItemBuilder .

Я предполагаю, что у этого ItemBuilder нет testLog метода, он определен ZeusBolt в. От get вас получается ItemBuilder объект.

Если вы хотите иметь возможность вызывать testLog , вам нужно привести его к правильному типу, например:

 ZeusBolt zeusBolt = (ZeusBolt) registry.get("ZEUS_BOLT");
zeusBolt.testLog();
 

В случае, если у вас есть объекты разных типов на карте, и вы хотите перебрать их все и выполнить соответствующую операцию на основе типа, вас может заинтересовать instanceof operator, чтобы проверить, имеет ли переменная заданный тип:

 ItemBuilder itemBuilder = registry.get("ZEUS_BOLT");
if (itemBuilder instanceof ZeusBolt){
    ZeusBolt zeusBolt = (ZeusBolt) itemBuilder;
    zeusBolt.testLog();
}
 

Комментарии:

1. Если бы я хотел получить элемент из реестра на основе пользовательского ввода, как бы я это сделал? Скажем, если бы у меня были ZeusBolt и класс Sword, оба расширяющие ItemBuilder, должен ли я проверять операторы if для каждого типа?

2. @JordanBaron Да, если вы хотите вызывать разные методы, вы должны это сделать.