关于java:构造函数中的继承

Inheritance in constructors

我的问题很大程度上与此有关。List 是List 的子类吗?为什么Java的泛型不是隐式多态的?

因此,假设我们有Animal,它是Cat and Dog的超级接口。我们还有一个抽象类Litter,使得

1
2
3
4
public abstract class Litter{

    public Litter(Collection<Animal> animals){}
}

然后我们自然有一个具体的类KittyLitter

1
2
3
4
5
6
public class KittyLitter extends Litter{

    public KittyLitter(Collection<Cat> animals) {
        super(animals);
    }
}

...和小狗垃圾。

自然地,我们希望将KittyLitter中的所有Animal限制为Cat。 Java为什么不允许我们这样做?然后,也可以说我们添加了另一种方法-

1
public abstract void addCub(Animal animal);

和KittyLitter在

中的具体实现

1
2
3
4
@Override
public void addCub(Animal cat) {
    // TODO Auto-generated method stub
}

在这一点上,这破坏了逻辑,并允许我们将Dog插入KittyLitter中,这没有任何意义。关于Java为什么要对我们做这些事情的任何想法?另外,如果可以将KittyLitter构造函数更改为接受List,为什么type参数的行为会有所不同?谁能解释为什么会这样吗?

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


您需要使超类泛型,使用有界类型参数来说明垫料可以容纳哪种动物:

1
2
3
4
5
6
7
8
9
10
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的类型,允许子类限制继承的超类方法将接受哪种动物。KittyLitteraddCub方法采用Cat自变量,而不是Animal。而PuppyLitteraddCub将采用Dog


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

必须能够像直接调用父类一样调用覆盖的方法,以便它们不能缩小参数类型。当Litter说可以与任何Animal一起调用时,则它必须能够与任何Animal

一起调用。