My question largely relates to this one Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?
So, say we have Animal that is a super interface of Cat and Dog. We also have a abstract class Litter such that
public abstract class Litter{
public Litter(Collection<Animal> animals){}
}
And then we naturally have a concrete class KittyLitter
public class KittyLitter extends Litter{
public KittyLitter(Collection<Cat> animals) {
super(animals);
}
}
...and puppy litter.
Naturally, we want to limit all Animal in a KittyLitter to just Cat. Why doesnt Java allow us to do this? Then, also lets say we add another method --
public abstract void addCub(Animal animal);
and concrete implementation in KittyLitter of
@Override
public void addCub(Animal cat) {
// TODO Auto-generated method stub
}
At this point this breaks logic and allows us to insert a Dog into a KittyLitter which makes no sense. Any ideas as to why Java does these things to us? Also, if KittyLitter constructor can be changed to accept a List, why does the type argument behave differently? Can anyone explain why this is so?
EDIT: this is really not about constructors, but also any method that overrides.
You need to make the superclass generic, using a bounded type parameter to say what kind of animals the litter can hold:
public abstract class Litter<T extends Animal> { // <-- type bound
public Litter(Collection<T> animals) { /* ... */ }
public void addCub(T cub) { /* ... */ }
}
public class KittyLitter extends Litter<Cat> {
public KittyLitter(Collection<Cat> cats) {
super(cats);
}
}
This allows the subclass to limit what kind of animals the inherited superclass methods will accept, by specifying a type for T. KittyLitter
's addCub
method takes a Cat
argument, not an Animal
. And PuppyLitter
's addCub
will take a Dog
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With