如何知道它是编译时多态还是运行时多态?

时间:2018-11-05 06:23:18

标签: java polymorphism override late-binding run-time-polymorphism

考虑一个超类:

class superclass
{
    public void fun() {.....}
}

及其子类:

class subclass extends superclass
{
    public void fun(){.......}
    public static void main()
    {
         superclass sup1=new superclass(); 
         sup1.fun()//statement 1
         superclass sup2=new subclass();
         sup2.fun() //statement 2
         subclass sub1=new subclass(); 
         sub1.fun()//statement 3
     }
}

我按照以下方式确定语句1,2和3是编译时多态还是运行时多态。

  • 编译器首先确定在调用语句中使用的引用变量的类类型,然后编译器检查源代码中是否存在该基数的派生类,以及是否覆盖了在调用语句中使用的方法或不在派生类中。如果找到了派生类,并且该类包含函数的重写版本,则在运行时确定引用变量所引用的对象的类型,并执行该类的类型函数(运行时多态性),否则该类中存在函数(属于该参考变量)(编译时多态)。

  • 通过这种方式进行: 1)语句1将导致运行时多态。

    2)陈述2也将导致运行时多态。

    3)陈述3将导致编译时多态。

问题1: 我想知道这种方法是对还是错?

问题2: 当使用函数调用语句代替对象变量返回对象的地址时,将执行什么步骤? 我认为返回地址的函数的返回类型将用于确定多态性的类型。 我说得对吗?

2 个答案:

答案 0 :(得分:1)

在Java中,对于任何可覆盖的方法,您始终具有运行时多态!编译器无法知道一个类的所有可能派生类,因此它不能遵循上面的算法。

AFAIK,逻辑如下:

  1. 在编译时,编译器使用变量的类型确定正确的签名。
  2. 在运行时,jvm使用实际对象的类型和在编译时确定的签名来确定正确的方法。

答案 1 :(得分:0)

我认为所有语句都是java中每个非静态方法在运行时绑定的运行时多态性。对象在运行时引用,因此在编译时不存在任何对象,因此,当您借助将在运行时绑定的对象的帮助来调用任何方法时,总是如此。 这在您的代码函数中被对象调用,这所有语句都是运行时多态 而另一件事是函数重写将始终是运行时多态性,因为引用将在运行时赋给对象 但是,当您覆盖将在运行时进行绑定的非静态函数时,或者当您覆盖静态成员时,仅当该函数将在编译时进行绑定