我在解释中又添加了一个子类。
Tree
/ \
/ \
/ \
Redwood Blackwood
在这个层次结构中:
Upcast:当我们沿类层次结构向一个方向投射引用时from the sub classes towards the root
。在这种情况下,我们不需要使用强制转换运算符
大写示例:
一个Redwood
或Blackwood
两者都是tree
:所以
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = b; // Valid
Downcast:当我们沿类层次结构向一个方向投射引用时from the root class towards the children or subclasses
。我们需要显式类型转换。
垂头丧气的例子:
Redwood r = new Tree(); //compiler error, because Tree is not a Redwood
Blackwood r = new Tree(); //compiler error, because Tree is not a Blackwood
Tree object
如果它确实指向 Redwood
对象或对象,则需要显式类型转换,否则Blackwook
在运行时会出错。例如
在这种情况下:
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = r; // Valid
Redwood r2 = (Redwood)t1;
Blackwood b2 = (Blackwood)t2
[回答]
Redwood r = (Redwood) new Tree();
为什么没有编译器错误?
它的Downcast示例:
源头Redwood r = (Redwood) new Tree();
创建 Tree 对象并类型转换为Redwood
.
你可以这样想:
Tree t = new Tree();`
Redwood r = (Redwood)t;
所以它在编译时没问题,
[回答]
为什么运行时错误?
但真正Redwood
的子类不能指向Tree
超级类对象。所以你的代码在运行时失败。
树 t = 新树();
t
指向Tree()
对象 not Redwood()
。这就是运行时错误的原因。
编译器现在不写什么是有价值的,t
并且在语法上每件事都是写的。但是在运行时由于,if的对象Redwood r = (Redwood)t;
在哪里出错了。 t
Tree class
[建议:]
我建议您使用instanceof运算符:
强制转换/强制操作用于在类型之间进行转换,instanceof运算符用于在运行时检查类型信息。*
说明:
instanceof运算符允许您确定对象的类型。它接受运算符左侧的对象和运算符右侧的类型,并返回一个布尔值,指示该对象是否属于该类型。举个例子最清楚地说明了这一点:
if (t instanceof Redwood)
{
Redwood r = (Redwood)t;
// rest of your code
}
但我还要补充一点:从基类型转换为派生类型是一件坏事。
参考:当心 instanceof 运算符