真的是多态吗?

Is it really polymorphism?

考虑一个名为 Shape 的接口,它有一个 draw() 方法。两个 类 TriangleCircle 实现了 Shape 接口并覆盖了 draw() 方法。 现在在 main 我有以下代码:

public static void main(String[] args){

    Shape shape = new Triangle();
    shape.draw();

    //Shape shape = new Circle();
    //shape.draw();
}

我发现这是多态性的一个例子,因为我们不知道在运行时将调用哪个绘制方法。解释说 While invoking shape.draw() the compiler sees draw() in the Shape interface at compile time, and the JVM invokes draw() in the Triangle class at run time. Same happens for the draw() in the Circle class.

我的疑惑是,这真的能叫多态吗?由于 new Triangle()new Circle() 是硬编码的,编译器不会总是知道它指向子 类' draw() 方法吗?

让我们编写相同的示例,但使用数组:

public static void main(String[] args){
    Shape[] shapes = new Shape[2];
    shapes[0] = new Triangle();    
    shapes[1] = new Circle();
    for(int i=0;i<shapes.length;++i){
        shape.draw();
    }
}

在我看来,它更能说明多态性。希望对你有帮助。

我觉得比较恰当的例子是

List<Shape> lstShape = new ArrayList<Shape>();
lstShape.add(new Circle());
lstShape.add(new Triangle());

...

for (Shape s: lstShape) {
    s.draw();
}

另见:http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

A,您正在使用父引用引用子对象,因此有知道在编译时调用哪个 draw() 的方法。

此外,您的编译器没有抛出任何错误并让您的代码得到编译,因为它知道 shape 有一个方法名称为 draw 而不是您的 Triangle 或 Circle 有没有那个,至于编译器唯一重要的事情当您执行 shape.draw() 时,方法 draw 的可访问性。您可以尝试仅将一种方法放在 Triangle 中,然后尝试使用 shape.xxx 编译器调用它,但不允许这样做。

现在,已经说过以上两点可以推导出来,A. 我们看到了可以在编译时解决的多态性,我们称之为静态多态性(例如,您的编译器允许您通过父级访问子引用)B.在运行时虽然你说shape.draw,但也不是调用父绘图而是调用子绘图,这只能在运行时解决,所以将其命名为运行时多态性。

希望我消除了你的疑虑。

Runtime 多态性的概念最好用 Factory 方法来解释,即 returns 一个基于输入的 Shape 对象。

工厂方法:

public static Shape getShape(int i){ 
              if(i == 1) {return new Triangle();}
              else{return new Circle();}  
}

属性 文件:

num:1

根据属性文件中的值,得到一个Shape对象。

public static void main(String[] args){

   int x = getFromPropertyFile();
   Shape shape = getShape(x); // Shape obtained from a factory method
   shape.draw(); //Runtime polymorphism
}

编译器不知道将返回哪个对象。它由作为输入提供的值在 运行 时间确定。您可以在 JDBC 驱动程序实现中看到这种实现,其中实现 class 是在 运行 时间确定的。

在你的例子中:

Shape shape = new Triangle();
shape.draw();

Shape shape = new Circle();
shape.draw();

The method binding happens at the compile time i.e which methods can be invoked on a given reference type is decided at the compile time.

The selection of the method’s implementation to execute happens at the run time i.e which implementation of the method to be executed i.e the super class version or one of the subclass’s version is decided at the run time.

为了实现多态性你可以试试这个

    public static void main(String[] args){

        SampleClass sample=new SampleClass(new Triangle() or new Circle())
                sample.draw();
       }

    Clas SampleClass
    {
    Shape shape;
    //constructor
     public SampleClass(Shape shape)
    {
         this.shape=shape;

     }
       public void draw()
     {
            shape.draw();
      }

}