我对Java泛型如何处理继承/多态感到困惑。

假设以下层次结构-

动物( parent )

-( child )

因此,假设我有一个doSomething(List<Animal> animals)方法。根据继承和多态性的所有规则,我将假设List<Dog>List<Animal>,而List<Cat>List<Animal>-因此可以将任何一个传递给此方法。不是这样如果要实现此行为,则必须通过说doSomething(List<? extends Animal> animals)明确告诉该方法接受Animal的任何子类的列表。

我了解这是Java的行为。我的问题是为什么?为什么多态性通常是隐式的,但是当涉及泛型时,必须指定它?

最佳答案

不,List<Dog>不是List<Animal>。考虑一下您可以使用List<Animal>做什么-您可以向其中添加任何动物...包括猫。现在,您可以在逻辑上将猫添加到一窝小狗中吗?绝对不。

// Illegal code - because otherwise life would be Bad
List<Dog> dogs = new ArrayList<Dog>(); // ArrayList implements List
List<Animal> animals = dogs; // Awooga awooga
animals.add(new Cat());
Dog dog = dogs.get(0); // This should be safe, right?

突然,你有一只非常困惑的猫。

现在,您无法将Cat添加到List<? extends Animal>中,因为您不知道它是List<Cat>。您可以检索一个值并知道它将是一个Animal,但是您不能添加任意动物。 List<? super Animal>则相反,在这种情况下,您可以安全地向其中添加Animal,但是您可能对List<Object>一无所知,因此可能一无所获。

关于java - List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59896348/

10-12 01:33
查看更多