Reputation: 489
I'm new to using generics (very late to the party, I know), and aren't sure if what I am trying to achieve is possible, and if so, how.
OK, this is a contrived example of what I am try to achieve, that hopefully shows the pattern without any clutter:
// 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) { }
}
So, basically what I am trying to do is make CatBowl implement PetBowl, but so that the addFood() method only allows CatFood to be added.
The only solution I have been able to come up with is:
...
// 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) { }
}
However, in my non-contrived case there are more parameters, and this ends up making for a lot of boilerplate all over the place, so I'm hoping for a "neater" solution.
Upvotes: 1
Views: 205
Reputation: 2223
Yes, the promise of the interface is that it can take a PetFood<Cat>
so if you where able to make it take CatFood
then you would limit the types the that your class can take ... and break the "interface".
Upvotes: 0
Reputation: 692121
This is not really linked to generics. The interface PetBowl<Cat>
has a method addFood(PetFood<Cat> food)
. So, any class implementing this interface should have such a method. addFood(CatFood food)
is not acceptable because it doesn't allow adding any kind of PetFoo<Cat>
, but only CatFood
.
It's the same as if you had
interface A {
void add(Object o);
}
class AImpl implements A {
public void add(String s);
}
Obviously, AImpl.add
doesn't override A.add
, because it only accepts String
s, and not Object
s.
Upvotes: 3