我有一个关于多态和显式转换的小问题。 这是问题所在: 我有3个公共课:
package x;
public class Shape
{
public void draw(){
System.out.println("draw a Shape");
}
}
package x;
public class Circle1 extends Shape
{
}
package x;
public class Circle2 extends Circle1
{
@Override
public void draw ()
{
System.out.println("draw Circle2");
}
}
我的演示课程是:
package x;
public class Demo
{
public static void main (String[] args)
{
Shape s1=new Circle2();
s1.draw();
((Shape)s1).draw();
}
}
此代码的输出为:
画圆圈2 画Circle2
我理解调用s1.draw()
上的draw()
方法的Circle2
的多态行为。
最后一行让我感到困惑,当我在s1上进行显式转换时如此:((Shape)s1)
,这意味着表达式((Shape)s1)
是一个类型为Shape的引用,因为显式转换,对吧?
如果是这样,为什么代码((Shape)s1).draw();
会调用draw()
中的Circle2
方法,而不是形状中的{?}}?
谢谢:)
答案 0 :(得分:3)
强制转换不会更改对象 的内容,只会更改编译器查看该对象的方式。
所以,即使你"思考"一个圆圈是一个'#34;只是一个形状"它仍然是一个圆圈。
Circle1
拨打Shape
'平局的唯一方法是通过调用{{1}来自 Circle1
内的 }
答案 1 :(得分:0)
当您显式(或隐式)将对象强制转换为超类型时,方法将始终遵循用于构造对象的类的实现。在你的情况下,因为你的对象是用new Circle2()
构造的,所以即使你施放它也总是一个Circle2。事实上,有一种简单的方法可以让你看到它。只需在代码中添加以下行:
Shape s2 = (Shape) s1;
System.out.println(s2.getClass().getName());
这将打印出您的s2
对象(从s1转换而来)所属的确切类:)您将看到它仍然是Circle2。
如果您想调用draw()
方法的超类型实现,则需要调用super.draw()
。