我有一个 C 类。E 类扩展了它。
E e = new E();
C c = new C();
为什么
e = (E) c;
经过进一步审查:虽然数值转换与转换对象具有相同的语法,但还是出现了一些混淆。无论如何,上面的代码并没有给出编译,而是一个运行时错误——所以在某些情况下可以将一个类转换为子类(否则代码将无法编译)。任何人都可以给出上述工作的例子吗?
还有:
K extends M
K k = new K();
((M) k).getClass()
给出 K
。这是为什么?它被转换为更通用的 M
!
假设我在 M 和 K 中都实现了一个 doIt() 方法。正在执行
((M) k).doIt();
给出 M 或 K 的 doIt()?
谢谢!
最佳答案
考虑一个真实世界的例子:
public class Dog extends Animal
所有的狗都是动物,但并非所有的动物都是狗。因此...
public class Cat extends Animal
只有当所讨论的 Animal 确实是 Dog 时,才能将 Animal 转换为 Dog。否则,它会迫使 Universe 将狗独有的属性(摇尾部、吠叫等)推断到动物身上。该动物很可能是一只具有独特属性的猫(咕噜声、严格的 self 清洁机制等)。如果无法进行转换,则会在运行时抛出 ClassCastException。
没有人想要一只发出咕噜咕噜声的狗。
((M) k).getClass() gives K. Why is that? It was casted to the more general M!
您已将 k 转换为 M,但所有类都有一个 getClass() 方法。 k 的类始终是 K,无论您是否将其引用转换到 M。如果您将 Dog 转换为 Animal 并询问它是什么动物,它仍然会回答它是一只狗。
事实上,强制转换为父类(super class)是多余的。 Dog 已经是 Animal 并且它拥有 Animal 的所有方法以及它自己的方法。许多代码分析工具(如 FindBugs)会通知您冗余转换,以便您删除它们。
Suppose I have a doIt() method implemented in both M and K. executing
((M) k).doIt();
gives M's or K's doIt()?
K 的 doIt() 原因同上。 Actor 对引用进行操作;它不会将对象转换为不同的类型。
Can you give an example of when casting (Dog doggy = (Dog) myAnimal) makes sense?
当然可以。想象一个接收动物列表进行处理的方法。所有的狗都需要带去散步,所有的猫都需要用鸟形玩具玩。为此,我们调用仅在 Dog 上存在的 takeForWalk()
方法,或仅在 Cat 上存在的 play()
方法。
public void amuseAnimals( List<Animal> animals ) {
for ( Animal animal : animals ) {
if ( animal instanceof Dog ) {
Dog doggy = (Dog)animal;
doggy.takeForWalk( new WalkingRoute() );
} else if ( animal instanceof Cat ) {
Cat puss = (Cat)animal;
puss.play( new BirdShapedToy() );
}
}
}
关于java - 关于Java多态和转换的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1082453/