Метод переопределения дженериков Java - PullRequest
1 голос
/ 09 августа 2011

Я новичок в использовании дженериков (очень поздно для вечеринки, я знаю), и не уверен, возможно ли то, чего я пытаюсь достичь, и если да, то как.

Хорошо, это надуманный пример того, чего я пытаюсь достичь, который, надеюсь, показывает шаблон без каких-либо помех:

// Pet and Cats
interface Pet { }
interface Cat extends Pet { }
class TabbyCat implements Cat { }

// Pet food and cat food
interface PetFood<T extends Pet> { }
interface CatFood extends PetFood<Cat> {}
class DryCatFood implements CatFood {}
class WetCatFood implements CatFood {}

// PetBowl
interface PetBowl<T extends Pet> {
    public void addFood(PetFood<T> food);
}

// CatBowl
class CatBowl implements PetBowl<Cat> {

    // this doesn't override method, why not?
    public void addFood(CatFood food) { }

    // this does
    public void addFood(PetFood<Cat> food) { }

}

Итак, в основном я пытаюсь сделать так, чтобы CatBowl реализовывал PetBowl, но метод addFood () позволяет добавлять только CatFood.

Единственное решение, которое мне удалось найти, это:

...

// PetBowl
interface PetBowl<T extends Pet, F extends PetFood<T>> {
    public void addFood(F food);
}

// CatBowl
class CatBowl implements PetBowl<Cat, CatFood> {

    public void addFood(CatFood food) { }

}

Тем не менее, в моем не надуманном случае есть больше параметров, и это в конечном итоге приводит к большому количеству шаблонов повсюду, поэтому я надеюсь на «более аккуратное» решение.

Ответы [ 2 ]

3 голосов
/ 09 августа 2011

Это на самом деле не связано с генериками. Интерфейс PetBowl<Cat> имеет метод addFood(PetFood<Cat> food). Таким образом, любой класс, реализующий этот интерфейс, должен иметь такой метод. addFood(CatFood food) недопустимо, поскольку не позволяет добавлять какие-либо PetFoo<Cat>, а только CatFood.

Это так же, как если бы у вас было

interface A {
    void add(Object o);
}

class AImpl implements A {
    public void add(String s);
}

Очевидно, AImpl.add не переопределяет A.add, потому что он принимает только String с, а не Object с.

0 голосов
/ 09 августа 2011

Да, обещание интерфейса состоит в том, что он может принимать PetFood<Cat>, поэтому, если вы в состоянии заставить его принять CatFood, тогда вы ограничите типы, которые может принимать ваш класс ... и сломаете " интерфейс».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...