类型不匹配与 ArrayLists 中的多态性
Posted
技术标签:
【中文标题】类型不匹配与 ArrayLists 中的多态性【英文标题】:Type Mismatch with polymorphism in ArrayLists 【发布时间】:2017-08-09 08:45:04 【问题描述】:这是我的代码:-
ArrayList<animal> myanimals = new ArrayList<animal>();
dog adog = new dog();
myanimals.add(adog);
System.out.println("" + myanimals.get(0).getClass());
dog newdog = myanimals.get(0);
我创建了一个 animals(superclass) 的ArrayList
作为myanimals
并存储了一个 dog(subclass) 作为第一个元素。然后myanimals.get(0)
返回一个狗类型的对象。当这个狗类型对象在语句dog newdog = myanimals.get(0)
中被狗类型引用引用时,它会显示错误消息:
类型不匹配,无法从动物转换为狗。
为什么会这样?
【问题讨论】:
欢迎来到 ***。请将代码和错误发布为文本,而不是图片 感谢您的编辑建议。 @Shashwat 【参考方案1】:方法调用myanimals.get(0)
返回Animal
类型的对象引用。尝试 Typecasating 将 Animal
作为 dog
像:-
dog newdog = (dog)myanimals.get(0);
编辑 1:您询问了以下行的输出
System.out.println(myanimals.get(0).getClass());
这实际上打印出dog
。为什么 ?让我们来看看。
你认为下面的程序应该输出什么:
animal a = new dog();
System.out.println(a.getClass());
这会按预期打印出dog
。但这并不意味着我们可以这样做:-
animal a = new dog();
dog d = a;
这会引发 Compile-Time 错误。同样是你的情况的问题。据说ArrayList
包含animal
。因此,即使您向其添加了dog
,它也会返回animal
。
【讨论】:
但是命令:System.out.println("" + myanimals.get(0).getClass()); 将输出显示为"类多态。狗”。这不是意味着 myanimals.get(0) 返回一个狗对象吗? 虽然正确,但这并不能回答 OP 关于“为什么”不允许这样做的问题 @AayushTaneja 现在看看我的答案。我希望这次编辑可以解决问题。【参考方案2】:基本上,ArrayList 的类型是animal
,您可以在其中添加任何种类的动物,不仅是狗,还包括猫、老鼠和鹦鹉。虽然在您的情况下基础类型确实是 dog
,但您不能安全地知道这一点。否则,您会遇到这种情况下的运行时异常:
ArrayList<Animal> myanimals = new ArrayList<Animal>();
Cat myCat = new Cat();
myanimals.add(myCat);
System.out.println("" + myanimals.get(0).getClass());
Dog newdog = myanimals.get(0); // <-- this would be runtime exception if Java compiler allowed this
【讨论】:
【参考方案3】:Java 是一种静态类型语言。 IE。 Java 编译器根据源代码检查代码是否存在类型不匹配。你的源代码说,myanimals.get(0)
是动物类型。
继承是一种“IS-A”关系,即 Dog IS-A Animal,可用作 Animal 类型变量的值。但相反的情况并非如此:Animal 不是 IS-A Dog,它只是可能(这使得铸造成为可能 - 稍后会详细介绍)。这就是你得到类型不匹配的原因。
只是在运行时,在你的源代码被编译成字节码(并且泛型类型被删除)很久之后,myanimals.get(0).getClass()
似乎是巧合的 Dog。编译器以前无法知道这一点。
这是有道理的:它可以防止静态分析可能捕获的运行时错误。
但你,开发者,肯定知道myanimals.get(0).getClass()
在运行时将是 Dog 类型,所以你可以像 Shashwat 的回答那样承担责任并应用强制转换。编译器仍然会检查这种转换是否可能,如果是的话 - 它会相信你的话。
【讨论】:
非常感谢您的帮助。 @iTollu以上是关于类型不匹配与 ArrayLists 中的多态性的主要内容,如果未能解决你的问题,请参考以下文章