Jes*_*mes 2 java inheritance casting
如果您想立即阅读问题,请跳至最后一句.
假设我们有一个接口和三个类:
interface I{}
class A implements I{}
class B extends A {}
Run Code Online (Sandbox Code Playgroud)
以下声明:
A a = new A();
B b = new B();
Run Code Online (Sandbox Code Playgroud)
现在,有一种经典的转换方式,它允许我将类型A(父类)的引用转换为类型B的对象(子类),如下所示:
a = b; //here a is no longer pointing at object A, and is now pointing at the same object b is pointing at.
b = (B) a; // the casting is now accepted by the compiler and during runtime as well.
Run Code Online (Sandbox Code Playgroud)
这里问题就在哪里.每当我看到一行代码都有多个转换时,我就无法读取它(字面意思),因此我无法理解它的含义.
例如,假设我们有这行代码:
a = (B)(I)b;
Run Code Online (Sandbox Code Playgroud)
你怎么读这个?a是对类型A的对象的引用,并且它被赋予类型B的对象的值(从左侧首先投射).但是等一下,b之前还有另一个演员(I).那么我们在这里有什么?它是一个被转换为(B)对象的接口吗?或者它是否被视为一个界面,也被投射为(B)?
我试图将其分解以避免混淆:
I temp = (I) b;// first line
a = (B) temp;// second line
Run Code Online (Sandbox Code Playgroud)
所以,首先,因为b是I(因为它扩展了实现I的A),所以编译器在运行时接受"第一行".
但是,"第二行",我们引用了一个对象A被赋予了类型B的值.乍一看,它没有任何问题.但后来我意识到I它不是A,也不是B,即使"第二行"中的演员阵容可以让编译器认为它是B类型的对象,但它不应该在运行时被接受.
所以我想回答的主要问题是如何解释以下行:
a = (B)(I)b;
Run Code Online (Sandbox Code Playgroud)
现实或你不想要的答案
这里真正的问题是粗心的goofball编写了糟糕的代码.真正的解决方案是; 要么不写蹩脚的代码或修复代码.
让我们继续作为一个傻瓜或你似乎想要的答案
java中有两种类型的转换; 向上和向下铸造.
向上转换是指将类型A的对象转换为接口I的实例; 你正在"继承"继承树.例如:
A aObject = new A();
I iObject = (I)aObject; // Up casting.
Run Code Online (Sandbox Code Playgroud)
向上转换的好处是编译器能够在编译时确定转换是否合法.
向下转换是指将类型I的对象转换为类型A的对象; 你正在"继承"继承树.例如:
A aObject;
I iObject = new A();
aObject = (A)iObject;
Run Code Online (Sandbox Code Playgroud)
编译器在编译时不知道向下转换是否成功.因此,向下转换可能会在运行时抛出异常.
令人困惑的代码:a = (B)(I)b;是向上投射(安全)和向下投射(不安全)的一个例子.
作为奖励,铸造绝不是必需的.将B对象直接分配给A引用总是安全的,因为B类扩展了A类.
解决:"粗心的goofball"似乎是强大的语言.它不是强大的语言,它是描述你的情况的最好方法.事实上,编写这样的代码的人应该被终止(可选地,让你的竞争对手雇佣他们).
| 归档时间: |
|
| 查看次数: |
1927 次 |
| 最近记录: |