在java中:
Base b = new Base();
Derived d = (Derived)b;
抛出ClassCastException
。为什么?为什么向下倾倒Exception
?我无法弄清楚原因。
答案 0 :(得分:21)
让我重命名你的课程以使事情更清楚。 Base
- > Animal
。 Derived
- > Cat
。
仅仅因为你是Animal
并不意味着你是Cat
。你可能是Dog
。这就是为什么将Animal
投射到Cat
中是违法的。
另一方面,每个Cat
是Animal
吗?答案是肯定的。这就是你可以编写这样的代码的原因:
Animal animal = new Cat();
或
Cat cat = new Cat();
Animal animal = cat;
另外值得注意的是你可以这样做:
Animal animal = new Cat();
Cat cat = (Cat) animal;
您可以执行此操作的原因是您的animal
变量实际上引用了Cat
实例。因此,您可以将其强制转换为引用Cat
的变量。
答案 1 :(得分:2)
您不能将派生类强制转换为基类。您可以将b
指定为Base
或Derived
,但您只能将d
指定为Derived
。简而言之,您只能将声明为Base
的变量指定为具有相同类型(Base
)或派生类型的值。
这没关系(我只是以new
为例,重要的是数据类型):
Base b = new Base();
Base b = new Derived();
Derived d = new Derived();
但这不是:
Derived d = new Base();
这是继承的工作方式
答案 2 :(得分:0)
派生类从其超类继承行为。因此,将子类对象转换为超类引用是有效的,因为 派生类对象能够履行超类 定义的契约。
另一方面,超类(通过你定义类的方式)显然没有实现子类中存在的大多数方法。那么,这就是为什么你首先扩展超类 - 扩展它的实现。
因此,将超类对象转换为子类类型是 本质上不安全的操作 ,因为基类对象无法完全履行其子类的合同
答案 3 :(得分:0)
要在Java中向下转换并避免运行时异常,请参考以下代码:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
}
在这里,动物是父类,而猫是子类。
instanceof 是用于检查引用变量是否包含给定类型的对象引用的关键字。