4

在java中:

Base b = new Base();
Derived d = (Derived)b; 

抛出ClassCastException。为什么?为什么在这里投掷向下投掷Exception?我无法弄清楚原因。

4

4 回答 4

22

让我重命名您的课程以使事情更清楚。 Base-> AnimalDerived-> Cat

仅仅因为你是一个Animal并不意味着你是一个Cat。你可能是一个Dog. 这就是为什么将 anAnimal转换为Cat.

另一方面,是每Cat一个Animal?答案是“是”。这就是为什么你可以编写这样的代码:

Animal animal = new Cat();

或者

Cat cat = new Cat();
Animal animal = cat;

另外值得注意的是你可以这样做:

Animal animal = new Cat();
Cat cat = (Cat) animal;

您可以这样做的原因是您的animal变量实际上是在引用一个Cat实例。因此,您可以将其转换回引用 a 的变量Cat

于 2013-06-18T20:14:37.907 回答
2

您不能将派生类强制转换为基类。您可以指定b为 aBase或 a Derived,但您只能指定d为 a Derived。长话短说,您只能分配一个声明为Base具有相同类型 ( Base) 或派生类型的值的变量。

这没关系(我只是new作为一个例子,重要的是数据类型):

Base b = new Base();
Base b = new Derived();
Derived d = new Derived();

但这不是:

Derived d = new Base();

这就是继承的工作方式

于 2013-06-18T20:17:15.087 回答
0

派生类从其超类继承行为。因此,将子类对象转换为超类引用是可行的,因为派生类对象能够履行由超类定义的契约

另一方面,超类(通过您定义类的方式)显然没有实现子类中存在的大多数方法。嗯,这就是你首先扩展超类的原因——扩展它的实现。

因此,将超类对象转换为子类类型本质上是不安全的操作,因为基类对象无法完全履行其子类的契约。

于 2013-06-18T20:25:45.890 回答
0

要在 Java 中向下转换并避免运行时异常,请参考以下代码:

if (animal instanceof Cat) {
  Cat cat = (Cat) animal;
}

这里,Animal 是父类,Cat 是子类。

instanceof是一个关键字,用于检查引用变量是否包含给定类型的对象引用。

于 2019-09-06T11:23:03.750 回答