我的问题主要涉及这一Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?
所以,我们说动物是Cat和Dog的超级界面。我们还有一个抽象类Litter,以便
public abstract class Litter{
public Litter(Collection<Animal> animals){}
}
然后我们自然会有一个具体的类KittyLitter
public class KittyLitter extends Litter{
public KittyLitter(Collection<Cat> animals) {
super(animals);
}
}
......还有小狗垃圾。
当然,我们希望将KittyLitter中的所有Animal限制为Cat。为什么Java不允许我们这样做?然后,还可以说我们添加另一种方法 -
public abstract void addCub(Animal animal);
和
的KittyLitter中的具体实现@Override
public void addCub(Animal cat) {
// TODO Auto-generated method stub
}
此时这打破了逻辑并允许我们将Dog插入KittyLitter,这是没有意义的。关于为什么Java会对我们做这些事情的任何想法?另外,如果可以将KittyLitter构造函数更改为接受List,为什么type参数的行为会有所不同?谁能解释为什么会这样呢?
编辑:这实际上不是关于构造函数,而是任何覆盖的方法。
答案 0 :(得分:5)
您需要使用bounded type parameter来表示超类的通用性,以说明垃圾可以容纳哪种动物:
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);
}
}
这允许子类通过指定T的类型来限制继承的超类方法将接受哪种动物。KittyLitter
addCub
方法需要Cat
参数,而不是Animal
。 PuppyLitter
&#39; addCub
将Dog
。
答案 1 :(得分:0)
构造函数不会覆盖超级构造函数,您可以使用您喜欢的任何参数声明它们。您也可以使用任何参数声明非重写方法。
必须能够调用重写的方法,就像直接调用父类一样,因此它们不能缩小参数类型。当Litter
表示可以使用任何Animal
调用它时,必须能够使用任何Animal
调用它。