简体   繁体   English

显式转换运算符和多态

[英]Explicit Casting operator and Polymorphism

I have a small issue with polymorphism and explicit casting. 我对多态性和显式转换有一个小问题。 Here is the problem: I have 3 public classes: 这是问题所在:我有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");
    }
}

And my Demo class is: 我的演示课是:

package x;

public class Demo
{
    public static void main (String[] args)
    {

        Shape s1=new Circle2();
        s1.draw();
        ((Shape)s1).draw();

    }
}

The output of this code is: 此代码的输出是:

draw Circle2 画Circle2
draw Circle2 画Circle2

I understand the polymorphic behavior of s1.draw() that invokes the draw() method on Circle2 . 我了解的多态行为s1.draw()调用的draw()的方法Circle2 The last line confuses me, when I do explicit casting on s1 like so: ((Shape)s1) , it means that the expression ((Shape)s1) is a reference of type Shape because of the explicit casting,right? 最后一行使我感到困惑,当我像这样对s1进行显式转换时: ((Shape)s1) ,这意味着表达式((Shape)s1)是Shape类型的引用,因为显式转换,对吗? And if that is so, why then the code ((Shape)s1).draw(); 如果是这样,那么为什么要使用代码((Shape)s1).draw(); invokes the draw() method in Circle2 and not the one in Shape? 调用Circle2draw()方法,而不是Shape中的Circle2

Thanks :) 谢谢 :)

Casting does not change what the object is , it simply changes how the compiler should look at that object. 铸造不会改变的对象什么,它只是改变了编译器应该如何看待该对象。

So even if you "think" of a Circle to be "just a shape" it still stays a Circle. 因此,即使您“认为”一个圆“只是一个形状”,它也仍然是一个圆。

The only way for a Circle1 to call Shape 's draw would be from within Circle1 by a call to super.draw() Circle1调用Shape的绘制的唯一方法是 Circle1通过调用super.draw()

When you explicitly (or implicitly) cast an object to a super type the methods will always obey the implementation of the class used to construct the object. 当您显式(或隐式)将对象转换为超类型时,方法将始终服从用于构造对象的类的实现。 In your case, because your object was constructed with new Circle2() , it will always be a Circle2, even if you cast it. 在您的情况下,因为您的对象是使用new Circle2()构造的,所以即使您对其进行投射,它也始终是Circle2。 In fact, there is an easy way for you to see that. 实际上,有一种简单的方法可以让您看到。 Just add the following lines to your code: 只需将以下行添加到您的代码中:

Shape s2 = (Shape) s1;
System.out.println(s2.getClass().getName());

This prints the exact class that your s2 object (casted from s1) belongs to :) you will see it is still a Circle2. 这将打印您的s2对象(从s1广播)所属的确切类:),您将看到它仍然是Circle2。

If you want to call the super type implementation of the draw() method you need to call super.draw() instead. 如果要调用draw()方法的超类型实现,则需要调用super.draw()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM