解决向上转型/向下转型问题
有人有任何可行的策略来解决铸造/升级问题吗?我理解何时允许向上转型和向下转型,但是当问题往往涉及多个对象时,我往往很快就会感到困惑。例如,寻找以下问题答案的最佳方法是什么:
问题:编译以下程序的结果是什么:
interface Inter{}
class Base implements Inter{}
class Derived extends Base{}
class ZiggyTest2{
public static void main(String[] args){
Base b = new Base();
Derived d = new Derived();
Inter i = (Base)b;
i = (Base)d;
Derived bd = (Derived)b;
b = (Base)i;
}
}
我对答案并不真正感兴趣,但更感兴趣的是解决问题的方法。我可以使用任何方法/策略来解决如上所述的向上转型/向下转型问题吗?例如,可以将引用/对象绘制在纸上,以便我可以获得视觉表示,这有帮助吗?
谢谢
Does anyone have any workable strategy for solving casting/upcasting questions? I understand when upcasting and downcasting is allowed but when the questions tend to have multiple objects involved i tend to get confused pretty quickly. For example, what is the best approach to finding the answer to a question like this:
Question: What would be the result of compiling the following program:
interface Inter{}
class Base implements Inter{}
class Derived extends Base{}
class ZiggyTest2{
public static void main(String[] args){
Base b = new Base();
Derived d = new Derived();
Inter i = (Base)b;
i = (Base)d;
Derived bd = (Derived)b;
b = (Base)i;
}
}
I am not really interested in the answer but more the approach to solve the question. Is there any approach/strategy i can use to solve an upcasting/downcasting question like above? For example can the references/objects be drawn on paper so that i can get a visual representation and can that help?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一篇关于向上转型和向下转型的很棒的文章。
引自文章 -
首先,您必须明白,通过强制转换,您实际上并没有改变对象本身,您只是以不同的方式标记它。
只需问自己一个问题“对象的类型是什么”目的?”然后记住,将其强制转换为类层次结构中的任何前驱类(包括接口)是合法的。
在您的例子中,您将创建 2 个对象:
Base
和Derived
。Base
可以标记为Inter
或Base
,Derived
可以标记为Inter< /code>、
基础
或派生
。所以,你的代码会编译得很好。但在运行时,当您尝试将Base b
转换为Derived bd
时,您将收到 ClassCastException。Here is a great article about upcasting and downcasting.
Quote from the article --
First, you must understand, that by casting you are not actually changing the object itself, you are just labeling it differently.
Just ask yourself the question "what is the type of the object?" and then remember that it is legal to cast it to any predecessor class in the class heirarchy (including interfaces).
In your case, you are creating 2 objects, a
Base
andDerived
. TheBase
can be labeled anInter
or aBase
and theDerived
can be labeled anInter
,Base
orDerived
. So, your code will compile just fine. But at runtime, when you try to castBase b
to aDerived bd
, you will get a ClassCastException.有一些简单的规则
前两条规则也适用于接口。
您可以绘制UML类图来可视化它(仅实现=实现,扩展实现) ,沿着箭头的方向浏览图表是安全的。导航到另一种方式将是运行时不安全的。并且在没有扩展/实现关系的情况下进行导航是不可能的。
There are some simple rules
first two rules applies ti intefaces as well.
You can draw UML class diagram to visualise it (with only implements = realizes, extends realetions), navigating through the graph would be safe in the direction of the arrows. Navigating the other way would be run-time usafe. And navigating without extends/implements relation would be impossible.
如果所操作的对象位于同一层次结构中,强制转换肯定可以编译通过,但在运行时可能会失败。
例如:
如果你写:
上面的代码将编译,但在运行时会失败。因为编译器所能做的就是检查这两种类型是否位于同一继承树中。编译器允许在运行时可能工作的事情。但是,如果编译器确定某些东西永远不会工作,它就会在运行时本身抛出错误。例如,
这肯定会失败,因为编译器知道 String 和 Dog 不在同一层次结构中。
相同的规则也适用于接口。
希望有帮助。
If the objects being operated are in the same hierarchy, casting will compile for sure, but it might fail at runtime.
E.g.:
If you write:
Above code will compile, but it will fail at runtime. Because all the compiler can do is check if the two types are in the same inheritance tree. Compiler allows things which might work at runtime. But if the compiler knows for sure that something will never ever work, it will throw error at runtime itself. E.g.
This will surely fail as the compiler knows that String and Dog are not in the same hierarchy.
The same rules apply to interfaces as well.
Hope it helps.
对我来说,我想首先绘制这些类型的层次结构。对于您的问题,类型的“级别”为:
Inter
(高于)Base
(高于)Derived
“级别”对象的“属性”是在创建时就确定的,根据创建级别,对象只能“向上”,不能“向下”。例如,对象
b
被创建为Base
对象,因此它处于Base
级别。你可以很容易地发现,无论使用什么类型来描述b,b
都可以向上转换为Inter
,但不能向下转换为Derived
。如果用Inter
来描述b,由于它的创建级别是Base
,所以可以将其向下转型为Base
。For me I'd like to first draw the hierarchy of these types. For your question, the "levels" of the types are:
Inter
(is higher than)Base
(is higher than)Derived
The "level" of an object is determined at its creation, and the object can only "go" up not down depending on its creation level. For example, Object
b
is created as aBase
object, so it is at the level ofBase
. You can easily find outb
can upcast toInter
but not downcast toDerived
, no matter what type is used to describe b. IfInter
is used to describe b, since its creation level isBase
, you can downcast it toBase
.