[英]Why Downcasting throws Exception?
在java中:
Base b = new Base();
Derived d = (Derived)b;
抛出ClassCastException
。 为什么? 为什么向下倾倒抛出Exception
呢? 我无法弄清楚原因。
让我重命名你的课程以使事情更清楚。 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
的变量。
您不能将派生类强制转换为基类。 您可以将b
指定为Base
或Derived
,但您只能将d
指定为Derived
。 简而言之,您只能将声明为Base
的变量赋值为相同类型( Base
)或派生类型的值。
这没关系(我只是以new
为例,重要的是数据类型):
Base b = new Base();
Base b = new Derived();
Derived d = new Derived();
但这不是:
Derived d = new Base();
这是继承的工作方式
派生类从其超类继承行为 。 因此,将子类对象转换为超类引用是有效的,因为派生类对象能够履行超类定义的契约 。
另一方面,超类(通过你定义类的方式)显然没有实现子类中存在的大多数方法。 那么,这就是为什么你首先扩展超级类 - 扩展它的实现。
因此,将超类对象转换为子类类型本质上是不安全的操作,因为基类对象无法完全履行其子类的契约。
要在Java中进行向下转换并避免运行时异常,请参考以下代码:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
}
这里,Animal是父类,Cat是子类。
instanceof是一个关键字,用于检查引用变量是否包含给定类型的对象引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.