【问题标题】:Is upcasting from the current object reference or actual object type?是从当前对象引用还是实际对象类型向上转换?
【发布时间】:2021-11-20 13:21:32
【问题描述】:

我在学校遇到一个问题,询问类型转换的种类以及是否会发生错误。

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

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

给定以下 UML 类图:

【问题讨论】:

    标签: java oop casting upcasting


    【解决方案1】:

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

    但是,加上演员表,肯定会的。

    这个:

    InterfaceA obj = new ClassB();
    

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

    然后,您分别建造房屋。房子没有名字。这所房子确实有一个红色屋顶(您要实例化的类实现了InterfaceA)。然后你在便利贴上写下这栋新建房子的地址,这没关系——毕竟它有一个红色的屋顶。

    房子不知道postit,也不在乎。便利贴的存在根本不会改变房子。不可能去房子然后问房子:你能告诉我全球所有带有你地址的邮政信箱的位置吗?用 java 术语来说:在一个对象上有一个变量点不会以任何方式修改该对象,根本不可能从一个对象转到引用它的变量。

    然后你做:

    ClassA obj2 = obj;
    

    这将创建另一个标题 postit。它的标题是'obj2',并且只允许在上面写砖房的地址。

    然后,您尝试使用您的obj postit(仅限于具有红色屋顶房屋的地址),并将地址复制到您的新 postit 上。你肯定不是在创建第二个房子(new 如果你想创建另一个对象,则需要在 java 中涉及),你只是在复制一个地址。

    邮政便条警察阻止了您:虽然您的obj postit 上的地址可能是砖砌的,但可能不是; obj postit 只能保证屋顶是红色的,不能保证它是用砖砌成的。

    使用强制转换操作:

    ClassA obj2 = (ClassA) obj;
    

    代码现在编译(如果您要运行它并从ClassB 中删除abstract 修饰符,它将成功运行)。铸造操作只是检查,它不会改变任何屋顶或以其他方式转换任何东西。这段代码会开到房子里,检查它是否是砖砌的。

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

    在任何情况下,转换运算符都不会转换任何东西,除非 () 中的东西是原始类型(转换运算符做了 3 件完全不同的事情:转换原始类型,类型检查具体类型,并告诉编译器关闭泛型而不检查任何东西)。

    【讨论】:

    • 感谢您的类比!您描述的演员操作是向上转换还是向下转换操作?或者两者都不是
    • java 语言规范没有使用这些词。所以,基本上,谁在乎?如果您的老师认为这很重要,那么“向上转换”往往是指将“狗”视为“动物”的想法-您永远不需要在Java中这样做;编译器已经知道这适用于所有狗。这是横向铸造。毕竟,ClassA 和 InterfaceA 在您的图片中是相邻的。 'casting' 是:这个 Foo 类型的东西?我断言它也是 Bar 类型。 'upcasting' 是:在你的照片中,Bar 位于 Foo 之上。向下转换是 Bar 在它的“下方”,等等。
    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2019-03-27
    • 2014-02-28
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多