Java多态练习

有人可以解释编译器/运行时如何在示例中运行适当的方法吗?有 6 个类和一个void m(/* ... */)具有不同参数的方法。我知道编译器会分析声明的类型。输出总是来自中产阶级的“M”。


public class All {}

public class Most extends All {}

public class Special extends Most {}


public class Top {

    public void m( All p )     { System.out.println("A"); }

}

public class Middle extends Top {

    public void m( All p )     { System.out.println("M"); }

    public void m( Special p ) { System.out.println("L"); }

}

public class Bottom extends Middle {

    public void m( Most p ) { System.out.println("V"); }

    public void m( Special p ) { System.out.println("X"); }

}


public class Main {


  public static void main(String[] args) {

    All all = new All();

    Most most = new Most();

    Special special = new Special();


    Top x = new Middle();

    Top y = new Bottom();

    Middle z = new Bottom();


    x.m( most );     // Output is M

    x.m( special );  // Output is M

    y.m( all );      // Output is M

    y.m( special );  // Output is M

    z.m( all );      // Output is M

    z.m( most );     // Output is M

  }

}


繁星点点滴滴
浏览 138回答 1
1回答

蝴蝶不菲

方法覆盖在运行时通过查看对象的运行时类型来解决。编译器也决定调用哪个方法,但它只能根据表达式的编译时类型来决定。对于对 的两次调用x,它们都Top.m(All)在编译时解析为。x是编译时类型Top,因此编译器只能查找 中声明的方法Top及其超类。编译器发现唯一可用的方法是m(All). 在运行时,要调用的方法被解析为Middle.m(All)。这是因为运行时类型x实际上是Middle,所以运行时将调用覆盖m(All)在Middle。为什么不叫Middle.m(Special)?编译器已经决定Top.m(All)应该调用。运行时只会检查运行时类型是否覆盖了它。编译器不知道有一个Middle.m(Special)因为x是编译时类型Top。这两个调用y是相似的。y的编译时类型仍然是Top,因此编译器将方法解析为Top.m(All). y是运行时类型Bottom。由于Bottom继承自Middle,它也覆盖Top.m(All)。实现与Middle. 因此在运行时调用被覆盖的方法。这两个电话z有点不同,但他们Middle.m(All)最终还是决心这样做。的编译时类型z是Middle,因此两个调用都解析为Middle.m(All)。请注意,没有Middle.m(Most),因此调用z.m(most)仍将解析为Middle.m(All)。在运行时,该方法仍然解析为,Middle.m(All)因为运行时类型Bottom不会覆盖Middle.m(All)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java