java - List<Dog> 是 List<Animal> 的子类吗?为什么 Java 泛型不是隐式多态的?

标签 java generics inheritance polymorphism

我对 Java 泛型如何处理继承/多态性有点困惑。

假设以下层次结构 -

动物(父级)

- ( child )

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

我明白这是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?

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

现在,您无法添加 CatList<? extends Animal>因为你不知道这是一个List<Cat> 。您可以检索一个值并知道它将是 Animal ,但不能添加任意动物。 List<? super Animal> 则相反。 - 在这种情况下,您可以添加 Animal安全地访问它,但您不知道可以从中检索什么,因为它可能是 List<Object> .

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

相关文章:

c++ - 在基类的复制构造函数上调用虚方法时多态性不启动

java - 修改数值数据类型,将其最小值设置为 1

java - 如何使用正则表达式从格式字符串中获取字符串元素?

java - 下面是我的用于查找重复项的 Java 程序。这里重复输出我只想重复的字符作为输出

java - 如何在没有 "unchecked"警告的情况下转换为(已知)泛型类型?

java - 泛型和非泛型类的类型推断和泛型构造函数

java - 如何解析并返回指向单独的 strings[] 或字符串的链接列表?

java - 如何检查读者的输入是否在 500 到 1000 之间?我不确定我是否走在正确的轨道上

java - 将泛型抽象父类(super class)绑定(bind)到多个非泛型实现类

c++ - operator= 和 C++ 中不继承的函数?