构造函数中的继承

时间:2015-08-15 01:30:55

标签: java inheritance constructor

我的问题主要涉及这一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参数的行为会有所不同?谁能解释为什么会这样呢?

编辑:这实际上不是关于构造函数,而是任何覆盖的方法。

2 个答案:

答案 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参数,而不是AnimalPuppyLitter&#39; addCubDog

答案 1 :(得分:0)

构造函数不会覆盖超级构造函数,您可以使用您喜欢的任何参数声明它们。您也可以使用任何参数声明非重写方法。

必须能够调用重写的方法,就像直接调用父类一样,因此它们不能缩小参数类型。当Litter表示可以使用任何Animal调用它时,必须能够使用任何Animal调用它。