它真的是多态吗?

时间:2015-01-19 06:55:59

标签: java oop 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();
}

我发现这是多态的一个例子,因为我们不知道在运行时会调用哪个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()方法?

5 个答案:

答案 0 :(得分:4)

Runtime多态的概念最好用Factory方法解释,该方法根据输入返回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驱动程序实现中看到这种实现,其中实现类是在运行时确定的。

在你的例子中:

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

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

方法绑定发生在编译时,即方法可以   在编译时决定在给定的引用类型上调用   时间。

     

选择要执行的方法的实现发生在   运行时间,即执行方法即可执行,即   超类版本或子类的一个版本决定于   运行时间。

答案 1 :(得分:1)

我认为更恰当的例子是

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

答案 2 :(得分:0)

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

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();
    }
}

从我的观点来看,它更好地说明了多态性。希望,它会帮助你。

答案 3 :(得分:0)

A,您使用父引用引用子对象,因此知道如何知道在编译时调用哪个draw()。

此外,你的编译器没有抛出任何错误并让你的代码被编译,因为它知道shape有一个方法名称作为draw而不是你的Triangle或Circle有没有,至于编译器只有重要的东西当你做shape.draw()时,是方法绘制的可访问性。您可以尝试仅在Triangle中放置一个方法,并尝试使用shape.xxx编译器调用它不会允许相同。

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

我希望我能让你怀疑。

答案 4 :(得分:0)

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

    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();
      }

}