显式Casting算子和多态

时间:2015-12-28 21:26:07

标签: java polymorphism

我有一个关于多态和显式转换的小问题。 这是问题所在: 我有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方法,而不是形状中的{?}}?

谢谢:)

2 个答案:

答案 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()