Reputation: 691
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.
Upvotes: 4
Views: 97
Reputation: 34563
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
.
Upvotes: 6
Reputation: 9609
Constructors are not overriding super constructors and you can declare them with any parameters you like. You can declare non-overriding methods with any parameters as well.
Overridden methods must be able to be called as if you call the parent directly so they cannot narrow parameter types. When Litter
says it can be called with any Animal
then it must be able to be called with any Animal
.
Upvotes: 0