0

考虑一个超类:

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:当使用返回对象地址的函数调用语句代替引用变量时,过程会是什么?我认为返回地址的函数的返回类型将用于确定多态的类型。我对么?

4

2 回答 2

1

在 Java 中,任何可覆盖的方法总是具有运行时多态性!编译器不能知道一个类的所有可能的派生,所以它不能遵循你上面的算法。

AFAIK,逻辑是这样的:

  1. 在编译时,编译器使用变量的类型确定正确的签名。
  2. 在运行时,jvm 使用实际对象的类型和编译时确定的签名来确定正确的方法。
于 2018-11-05T07:26:27.907 回答
0

我认为所有语句都是java中的运行时多态性,每个非静态方法在运行时绑定。对象在运行时引用,因此在编译时不存在任何对象,所以当您在运行时绑定的对象的帮助下调用任何方法时总是如此。在您的代码中,函数由对象调用,所有语句都是运行时多态性,另一件事是函数覆盖将始终是运行时多态性,因为引用将在运行时分配给对象,但函数重载可能在运行时或在编译时,当您重载将在运行时绑定的非静态函数时,或者当您重载静态成员时,只有该函数将在编译时绑定

于 2018-11-05T07:50:52.400 回答