您好,我有几个关于类型转换和继承的问题。我一直在做一些阅读,我了解类型转换的重点和基础知识。但是,我不完全了解我可以在哪里使用它,不能使用它。
考虑这个类:
class A{
public A(){}
}
A temp = new A();
temp = (Object)temp;
此代码给我错误"无法从对象类型转换为 A 类型"。但是,这不会从类型 A 转换为类型 Object 吗?你不能键入向上层次结构吗?
现在我的第二个问题是关于继承之类的。
当您键入:
Object temp = new A();
到底发生了什么?temp 是 A 还是对象?
JLS 8.1.3的摘录:
如果类声明为任何其他 类没有扩展子句,则 类具有类
Object
作为其 隐式直接超类。
当然,Object
本身有点特别(JLS(:
除
Object
之外的每个类都是一个 的扩展(即的子类( 单个现有类 (§8.1.3( 和 可以实现接口 (§8.1.4(。
每个班级都是Object
的后代。
在您的情况下,您正在尝试将A
的对象存储到名为 A
的类对象中。这是行不通的。您需要做:
Object testObject = (Object)temp;
这会将Object
存储到 testObject
中,该具有您强制转换为的类型Object
。
在这里,它正在研究 ideone。
这只是因为您无法将超类对象分配给子类引用。
所以你不能做:
temp = (Object)temp;
因为它与:
Object newObject = new Object();
A temp = newObject;
您将在此处收到相同的编译错误。
当然,你可以做这样的事情:
Object newObject = new Object;
A temp = new A();
newObject = temp;
您可以这样做,因为您可以将子类分配给超类引用
问题出在最后一行。首先,你通过语句向 Java 保证 temp 的类型是 Object:
(Object) temp
之后,您尝试将编译器认为是 Object 类型的对象分配给应该属于 A 类型的变量。因此,总而言之,将 temp 转换为 Object 类型的部分很好,问题是当您之后尝试将其分配给期望类型 A 的变量时。
对于你的第二个问题,temp是A。使用 new 关键字创建对象时,对象的类型将始终是紧随其后的任何内容。在您的例子中 A. 之后,您将 temp 分配给 Object 类型的变量,但这不会更改 temp 的实际类型。拥有某种类型的 X 变量只是告诉你变量指向的任何内容都是 X 的子类型。
A a = (Object)temp;
"无法从对象类型转换为类型 A"。但是,这不会从类型 A 转换为类型 Object 吗?你不能键入向上层次结构吗?
你是对的
(Object)temp;
正在转换temp
,这是一个A
到一个Object
。但是,这不是编译器所抱怨的。现在你已经有效地,
A a = anObjectNOTAnA
(A = ...
是无效代码。我已将其更改为A a = ...
。
它说你不能将Object
转换回A
,除非你明确地强制转换它并可能禁止未选中的强制转换警告:
A a = (A)anObjectNOTAnA
或
@SuppressWarnings("unchecked")
A a = (A)anObjectNOTAnA
关于你的另一个问题:
Object temp = new A();
到底发生了什么?temp 是 A 还是对象?
转换任何类型的对象时,它永远不会更改基础对象的实际类型。new A()
总是A
,无论其
A a = new A();
或
Object objButReallyA = new A();
或
@SuppressWarnings("unchecked")
A a = (A)((Object)new A());
如果一个A
存储在一个Object
中,它只是同一对象的不同"视图"。但是,为了使用A
特定功能,必须首先将其恢复为A
视图:
objButReallyA.getAOnlyField(); //compile error
((A)objButReallyA).getAOnlyField(); //Okay