在java中:
Base b = new Base();
Derived d = (Derived)b;
抛出ClassCastException
。为什么?为什么在这里投掷向下投掷Exception
?我无法弄清楚原因。
在java中:
Base b = new Base();
Derived d = (Derived)b;
抛出ClassCastException
。为什么?为什么在这里投掷向下投掷Exception
?我无法弄清楚原因。
让我重命名您的课程以使事情更清楚。 Base
-> Animal
。 Derived
-> 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
。
您不能将派生类强制转换为基类。您可以指定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();
这就是继承的工作方式
派生类从其超类继承行为。因此,将子类对象转换为超类引用是可行的,因为派生类对象能够履行由超类定义的契约。
另一方面,超类(通过您定义类的方式)显然没有实现子类中存在的大多数方法。嗯,这就是你首先扩展超类的原因——扩展它的实现。
因此,将超类对象转换为子类类型本质上是不安全的操作,因为基类对象无法完全履行其子类的契约。
要在 Java 中向下转换并避免运行时异常,请参考以下代码:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
}
这里,Animal 是父类,Cat 是子类。
instanceof是一个关键字,用于检查引用变量是否包含给定类型的对象引用。