首页 > 解决方案 > 以下代码是否将后期绑定应用于静态方法?多态 Java

问题描述

所以我在玩 Java 来理解多态的概念,我写了这个:

public class Practice 
{
    public static void main(String[] args) 
    {
        Parent p = new Child();
        
        p.instanceMethod();
    }
}

class Child extends Parent {
     public void instanceMethod(){
         System.out.println("child's instance method");
         staticMethod();
     }
     public static void staticMethod() {
         System.out.println("child's static method");
     }
}

class Parent {
     public void instanceMethod(){
         System.out.println("parent's instance method");
         staticMethod();
     }
     public static void staticMethod() {
         System.out.println("parent's static method");
     }
}

所以这个的输出是:

child's instance method
child's static method

为什么从子类调用静态方法而不是从它的静态类型,父类?

是不是因为它首先被子类中的实例方法调用,所以此时它的类型已经是完全动态的,也就是子类的类型?

标签: javadynamicbindingstaticpolymorphism

解决方案


静态方法不会“做”多态性。完全没有。

非静态(即实例)方法可以。方法的签名完全是静态绑定的;查找在类型层次结构中实际运行的方法的实际前景完全是动态完成的(后期绑定)。

对于静态方法,整个事情完全是静态的。

那么,让我们来看看这段代码:

p.instanceMethod()

表达式p的类型是Parent。编译器查看可用的签名Parent及其所有超类型,并确定此调用instanceMethod()尝试调用的完整方法签名是void instanceMethod(). 此调用(Parent:: instanceMethod()Vin bytecode speak)被编码在发出的 .class 文件中。

在运行时,系统检查表达式解析为的实际运行时类型p(这是new Child()您之前所做的),并进行动态调度。的public void instanceMethod()ofChild明显覆盖了 from 的一个Parent,因此被选中并执行,因此"child's instance method"被打印。

staticMethod()在儿童

接下来,让我们看一下 staticMethod 调用:在编译时,javac 确定 this 显然是staticMethod()对那里的引用,在Child. 它在字节码中将字节码编码INVOKESTATICChild:: staticMethod()V。动态分派现在或从未应用于静态方法调用。

在运行时..调用该方法。

就那么简单。

也许您期望静态方法仍然首先检查调用上下文,但这不是 java 的工作方式。


推荐阅读