【问题标题】:Type Mismatch with polymorphism in ArrayLists类型不匹配与 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) 中被狗类型引用引用时,它会显示错误消息:

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

为什么会这样?

【问题讨论】:

  • 欢迎来到 StackOverflow。请将代码和错误发布为文本,而不是图片
  • 感谢您的编辑建议。 @Shashwat

标签: java oop arraylist polymorphism


【解决方案1】:

方法调用myanimals.get(0) 返回Animal 类型的对象引用。尝试 TypecasatingAnimal 作为 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
    猜你喜欢
    • 2015-02-03
    • 2014-09-18
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2013-03-22
    相关资源
    最近更新 更多