在ArrayLists中键入Mismatch with polymorphism

时间:2017-03-17 17:14:39

标签: java oop arraylist polymorphism

这是我的代码: -

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);

我创建了一个ArrayList 动物(超类)作为myanimals并存储了一个狗(子类)作为第一个元素。然后myanimals.get(0)返回一个狗类型对象。当此类型对象在语句dog newdog = myanimals.get(0)中由狗类型引用引用时,它会显示错误说明:

  

类型不匹配,无法从动物转换为狗。

为什么会这样?

3 个答案:

答案 0 :(得分:4)

方法调用myanimals.get(0)返回类型为Animal的对象引用。尝试{strong> 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;

这会抛出编译时错误。同样是你的案子的问题。据说ArrayList包含animal。因此,即使您向其添加animal,它也会返回dog

答案 1 :(得分:2)

Java是一种静态类型语言。即Java编译器根据源代码检查代码是否存在类型不匹配。您的源代码说,myanimals.get(0)属于Animal类型。

继承是一种“IS-A”关系,即Dog IS-A Animal,可以用作Animal类型变量的值。但事实恰恰相反:动物不是IS-A狗,它可能是(这使得铸造成为可能 - 后来更多)。这就是你输入类型不匹配的原因。

只有在运行时,在将源代码编译成字节码(并删除泛型类型)很久之后,myanimals.get(0).getClass()看起来似乎是巧合。编译器之前无法知道。

这是有道理的:它可以防止静态分析可能捕获的运行时错误。

但是,你是开发人员,他肯定知道,myanimals.get(0).getClass()在运行时会是Dog类型,所以你可以像在Shashwat的回答中那样承担责任并应用强制转换。编译器仍会检查是否可以进行此类转换,如果是,则会相信您的话。

答案 2 :(得分:0)

基本上,ArrayList的类型是<!DOCTYPE html> <html> <head> <title>Tip</title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> </head> <body> <% if notice %> <p class="alert alert-success"><%= notice %></p> <% end %> <% if alert %> <p class="alert alert-danger"><%= alert %></p> <% end %> <%= yield %> </body> </html> ,你可以添加任何种类的动物,不仅仅是狗,还有猫,老鼠和鹦鹉。虽然您的案例中的基础类型确实是animal,但您无法安全地了解这一点。否则,您将遇到运行时异常,如下所示:

dog