在Java中向下演员

时间:2013-05-09 09:21:04

标签: java casting downcast

有人可以向我解释为什么在将父母向下传播给孩子时会出现java.lang.ClassCastException吗?

public class Child extends Parent{
public static void main(String[] args){
    new Child().go();
}
void go(){
    go2(new Parent(), new Child());
    go2((Child) new Parent(), new Child());
}
void go2(Parent p1, Child c1){
    Child c2 = (Child)p1;
    Parent p2 = (Parent)c1;
} 
}
class Tree{}

我已阅读参考变量cast并在网上搜索示例。有人可以向我解释一下吗?我真的很想知道它为什么会抛出异常。感谢

6 个答案:

答案 0 :(得分:3)

让我们说一下Parent类Animal和Child类Bird。 你可以从Bird到Animal,因为所有的鸟都是动物。 你不能从动物到鸟类,因为并非所有动物都是鸟类。

答案 1 :(得分:2)

以下是您的问题代码被剥离:

go2(new Parent());

...

void go2(Parent p1){
    Child c2 = (Child)p1;
}

编译器允许您将p1从'Parent'转换为'Child',因为p1 可以成为'Child'。但是你可以明显看出,p1不是孩子。所以你的代码在编译时很好,但会在运行时崩溃。

这意味着,您可能在“Child”类中定义的所有添加的行为都不可用,因为您只有Type“Parent”的实例。

答案 2 :(得分:1)

  

您可以将Child投射到Parent。由于Child延伸Parent,   Child的任何实例都是Parent(但只有额外的内容   可用于Child)。但是,p1Parent。由于Parent   不是Child,您不能将Parent的实例强制转换为   Child

我从google search复制了类似问题的答案。请在下次做作业并阅读常见问题。

答案 3 :(得分:0)

Parent不是Child。也就是说,Parent确实有必要的字段被视为Child的实例,并且满足所有Child特定方法 - Child的合同。想象一下,如果Child有变量childOnly和方法childProcess,并且您尝试在内存中childProcess的对象上调用Parent。它无法工作,因此Java阻止您将父母视为孩子。

答案 4 :(得分:0)

由于多态引用,当您将sub-type对象存储到super-type引用时,您无法使用特定于sub-type的方法。但你可以得到super-type中定义的方法。

为了能够使用子类型方法,您需要将super-type的引用强制转换为sub-type

Parent p = new Child();
...
...
((Child)p).childMethod();

但只有当您知道分配给p的对象实际上属于Child类型时,才能执行此操作。否则它会给ClassCastException

答案 5 :(得分:0)

让我们说Car是一个裸骨接口

Merc is a Car (Merc extends Car)

BMW  is a Car (BMW extends Car)

现在

你可以把宝马和对待它的裸车作为宝马汽车的所有功能。所以你可以把宝马变成汽车,所以(Car car = (Car)bmw) 是合法的

如果你驾驶一辆裸骨车并尝试将其作为宝马来对待,那么宝马将拥有的不仅仅是一辆裸车。

所以,

BMW bmw = (BMW)car 是非法的

同样的现实世界概念扩展到面向对象的世界。