它不会编译;保证为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 件完全不同的事情:转换原始类型,类型检查具体类型,并告诉编译器关闭泛型而不检查任何东西)。