列出<狗> List< Animal>的子类?为什么Java泛型不是隐含多态的? [英] Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?

查看:99
本文介绍了列出<狗> List< Animal>的子类?为什么Java泛型不是隐含多态的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



假设以下层次结构 -



动物(家长)

/ p>

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

我明白这是Java的行为。我的问题是为什么?为什么多态一般是隐含的,但是当涉及到泛型时,它必须被指定?

解决方案

不,列表< Dog> 不是 a List< Animal> 。考虑你可以用 List< Animal> 做些什么 - 你可以添加任何动物......包括一只猫。现在,你可以在一只小狗上合理地添加一只猫吗?绝对不是。

  //非法代码 - 因为否则,生活将会是坏的
List< Dog> dogs = new ArrayList< Dog>(); // ArrayList实现列表
List< Animal>动物=狗; // Awooga awooga
animals.add(new Cat());
狗狗= dogs.get(0); //这应该是安全的,对吧?

突然之间,您有一只非常迷惑的猫



现在,您不能将 Cat 添加到 List< ;?由于您不知道它是 List< Cat> ,所以扩展Animal> 。你可以检索一个值并知道它是一个 Animal ,但你不能添加任意的动物。对于列表<? super animal> - 在这种情况下,您可以安全地添加一个 Animal ,但您不知道可能从中检索的内容,因为它可能是 List< Object>


I'm a bit confused about how Java generics handle inheritance / polymorphism.

Assume the following hierarchy -

Animal (Parent)

Dog - Cat (Children)

So suppose I have a method doSomething(List<Animal> animals). By all the rules of inheritance and polymorphism, I would assume that a List<Dog> is a List<Animal> and a List<Cat> is a List<Animal> - and so either one could be passed to this method. Not so. If I want to achieve this behavior, I have to explicitly tell the method to accept a list of any subset of Animal by saying doSomething(List<? extends Animal> animals).

I understand that this is Java's behavior. My question is why? Why is polymorphism generally implicit, but when it comes to generics it must be specified?

解决方案

No, a List<Dog> is not a List<Animal>. Consider what you can do with a List<Animal> - you can add any animal to it... including a cat. Now, can you logically add a cat to a litter of puppies? Absolutely not.

// 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?

Suddenly you have a very confused cat.

Now, you can't add a Cat to a List<? extends Animal> because you don't know it's a List<Cat>. You can retrieve a value and know that it will be an Animal, but you can't add arbitrary animals. The reverse is true for List<? super Animal> - in that case you can add an Animal to it safely, but you don't know anything about what might be retrieved from it, because it could be a List<Object>.

这篇关于列出&lt;狗&gt; List&lt; Animal&gt;的子类?为什么Java泛型不是隐含多态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆