Java: Может ли Vector <derived>называться Vector <base>? - PullRequest
1 голос
/ 06 февраля 2011

У меня есть класс foo, класс, производный от еды, называемый bar, и у меня есть метод в foo, который принимает другой foo

boolean baz(foo c)
{
return (condition)?true:false;
}

Я хочу написать перегрузку для baz, которая принимает Vector и вызывает baz для всех из них - что-то вроде

boolean baz(Vector<foo> v)
{
    for(int i=0;i<v.size();++i)
    {
    if baz(v.get(i))
        return true;
    }
    return false;
}

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

Чего мне не хватает?

Ответы [ 3 ]

6 голосов
/ 06 февраля 2011

Это ожидается, потому что генерики являются инвариантами.

List<Derived> не List<Base>.Представьте, что вы вызываете этот метод, но внутри него вы вызываете list.add(anotherDerived).

. Вы можете «исправить» это с помощью List<? extends Base>.Таким образом, вы не сможете добавлять элементы и, следовательно, не сможете нарушить договор об генерике.

(я использую List вместо Vector, потому что Vector заменен(в большинстве случаев) на ArrayList)

6 голосов
/ 06 февраля 2011

Просто объявите метод следующим образом:

boolean baz(Vector<? extends foo> v)

Два дополнительных пункта:

  • Java имеет чрезвычайно строгое соглашение для имен классов, начинающихся с заглавной буквы. Любой, кто читает ваш код, будет раздражен строчными именами классов.
  • Vector - это устаревший класс, который больше не должен использоваться, если вы не имеете дело с API, который имеет и который вы не контролируете (например, некоторые части AWT). Вместо этого используйте ArrayList.
1 голос
/ 06 февраля 2011

вместо:

boolean baz(Vector<foo> v)

try

boolean baz(Vector<? extends foo> v)
...