2017-03-17 21 views
1

以下类型不匹配是我的代码: -与多态性的ArrayList

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

欢迎来到StackOverflow。请将代码和错误发布为文字,而不是图片 –

+0

感谢您的编辑建议。 @Shashwat –

回答

4

方法调用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; 

这将抛出一个编译时错误。你的情况同样如此。据说ArrayList包含animal。因此,即使您为其添加dog,它也会返回animal

+0

但是命令:** System.out.println(“”+ myanimals.get(0).getClass()); **将输出显示为**“class polymorph.dog”**。这是否意味着** myanimals.get(0)**返回一个狗对象? –

+0

虽然正确,但这并不回答关于“为什么”不允许的OP问题 – bc004346

+0

@AayushTaneja现在查看我的答案。我希望这个编辑能够解决问题。 –

0

基本上,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 
+2

非常感谢。这非常有帮助。 @ bc004346 –

2

Java是静态类型语言。即Java编译器根据源代码检查类型不匹配的代码。你的源代码说,myanimals.get(0)是动物类型。

继承是“IS-A”关系,即狗IS-A动物,可以用作动物类型变量的值。但是相反的事实并非如此:动物不是IS-A狗,它可能是(它使得铸造成为可能 - 稍后会有更多)。这就是为什么你会遇到类型不匹配的原因。

它只是在运行时,很久以后你的源代码被编译成字节码(和泛型类型被擦除),myanimals.get(0).getClass()似乎是巧合的狗。编译器之前无法知道。

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

但是,你是开发者,他肯定知道myanimals.get(0).getClass()在运行时是Dog类型的,所以你可以承担责任并且在Shashwat的回答中应用cast。编译器仍然检查这样的转换是否可能,如果是的话 - 它会相信你的话。

+0

非常感谢您的帮助。 @iTollu –

+0

@ aayush-taneja欢迎您! – iTollu