是从当前对象引用还是实际对象类型向上转型?

Is upcasting from the current object reference or actual object type?

我在学校遇到一道题,问的是那种类型转换,会不会出错

InterfaceA obj = new ClassB();
ClassA obj2 = obj;

我知道第一行会导致编译时错误,因为 ClassB 是抽象的。但是,第二行是否可以从具有对象引用 InterfaceA 的实际对象类型 ClassB 向上转换到 ClassA? (如果 ClassB 不是抽象的)

给定以下 UML class 图:

它不会编译;保证类型为 InterfaceA 的 object 不保证也一定是类型 ClassA。即使在您编写此代码时 ClassB 是唯一可用的 class 实现 InterfaceA(代码未设置为琥珀色;也许有人稍后会写另一个 class) .

但是,添加演员表,当然可以。

这个:

InterfaceA obj = new ClassB();

正在创建 2 个完全不相关的东西。一个名为 obj 的局部变量,类似于带有标题的便利贴,您可以在上面写上地址。便利贴受到限制;你只能在上面写通往红屋顶房子的地址。 (假设这就是 InterfaceA 所代表的)。

然后,您单独盖房子。房子没有名字。这所房子确实有一个红色的屋顶(class 你正在实例化的工具 InterfaceA)。然后你在你的贴子上潦草地写下这个新建房子的地址,没关系——毕竟它有一个红色的屋顶。

房子不知道邮寄的事,也不在乎。 post-it 的存在根本不会改变房子。不可能去房子然后问房子:你能告诉我全世界所有写有你地址的邮寄的位置吗?在 java 术语中:在 object 处有一个变量点不会以任何方式修改 object,不可能从 object 到变量( s) 完全引用它。

然后你做:

ClassA obj2 = obj;

这将创建另一个带标题的便利贴。它的标题是 'obj2',并且仅限于在上面写 brick-built 个房屋的地址。

然后您尝试使用您的 obj 便利贴(限于只有红色屋顶房屋的地址),并将地址复制到您的新便利贴上。你当然不是在创建第二个房子(如果你想创建另一个 object,new 需要参与 java),你只是复制一个地址。

虽然警察会阻止您:虽然您 obj 便利贴上的地址 可能 是 brick-built,但它可能不是; obj postit 只能保证屋顶是红色的,不能保证它是砖砌的。

使用强制转换操作:

ClassA obj2 = (ClassA) obj;

代码现在可以编译(如果您要 运行 它并从 ClassB 中删除 abstract 修饰符,它将 运行 成功)。转换操作只是检查,它不会改变任何屋顶或以其他方式转换任何东西。该代码将开车到房子,检查它是 brick-built。

如果是,太好了,您可以复制地址。如果不是,则抛出 ClassCastException。

在任何情况下,强制转换运算符都不会转换任何东西,除非 () 中的内容是基本类型(强制转换运算符做 3 件完全不同的事情:转换基本类型,检查具体类型,并告诉编译器闭嘴不检查任何泛型)。