Добавление в общий набор, переданный в метод

17

Скажем, у меня есть следующие классы:

  • Animal
  • Cat
  • Собака
  • Корова

Животное - это базовый класс, кошка, собака и корова каждого подкласса.

Теперь у меня есть Set<Cat> , Set<Dog> и Set<Cow> , каждый из которых используется одинаково, поэтому имеет смысл сделать на них общую функцию:

private boolean addObject(Animal toAdd, Animal defVal, Set<? extends Animal> vals)

Это отлично работает, я могу свободно проходить в своих наборах без проблем.

Возникает проблема: я не могу попытаться добавить Animal toAdd в параметр vals. Googling показывает, что если я изменю метод следующим образом:

private boolean addObject(Animal toAdd, Animal defVal, Set<? super Animal> vals)

Я смогу добавить Animal в параметр vals. Это работает, за исключением теперь, я не могу пройти в своих подклассах моих наборов кошек, собак и коровы. Дальнейшие исследования говорят мне, что следующие работы, без предупреждений для загрузки:

private <T> boolean addObject(T toAdd, T defVal, Set<? super T> vals)

Проблема заключается в том, что мне нужно иметь возможность выполнять вызовы методов, которые есть у Animal. Это легко получить с помощью простого нажатия:

((Animal)toAdd).getAnimalType()

Есть ли какой-либо путь вокруг этой проблемы, поэтому я могу сохранить общие функции и не требовать кастинга? Помимо того, что мои наборы всех наборов базового типа, Animal в этом примере?

    
Спасибо за это благодарю
задан Legowaffles 08.03.2013 в 12:54
источник
  • есть способ, которым я могу использовать <> без использования html-кода здесь? => да, см. мои правки. Вам редко нужно использовать html на SO. –  assylias 08.03.2013 в 12:57
  • +1 Для ваших предыдущих исследований. К сожалению, это редкая вещь на этом сайте. –  Duncan Jones 08.03.2013 в 12:59
  • @assylias. Теперь, если бы я мог вспомнить, что в следующий раз мне нужно задать вопрос. –  Legowaffles 08.03.2013 в 13:05
  • @ DuncanJones Я честно довольно ленив, поэтому я вообще пытаюсь решить проблему самостоятельно, прежде чем пытаться задать вопрос. –  Legowaffles 08.03.2013 в 13:05
  • @Legowaffles SO использует Markdown для форматирования. –  assylias 08.03.2013 в 13:07

1 ответ

13

Хорошее исследование, вы были почти там. Вам просто нужно добавить верхнюю границу для T .

private <T extends Animal> boolean addObject(T toAdd, T defVal, Set<? super T> vals)
    
ответ дан Ben Schulz 08.03.2013 в 12:57
  • Спасибо, это работает. Я помечаю это как ответ через 8 или около того минут, когда это возможно. –  Legowaffles 08.03.2013 в 13:01
  • Возможно, было бы полезно указать, что означает эта подпись метода. Это означает: «Учитывая некоторый тип T, который является либо Animal, либо подклассом Animal (например, Cat), этот метод принимает два аргумента типа T плюс набор из T (например, Set <Cat>) или некоторого типа, который является супертип T (например, Set <Animal>). " Опуская? супер из аргумента Set все равно позволит это работать, просто не с помощью Set <Animal>. Но Set <? extends Animal> не работает, потому что <? extends Animal> означает «некоторый тип, который является либо Animal, либо подклассом Animal, но я не знаю, какой подкласс». –  Daniel Pryden 09.03.2013 в 06:51