You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Dynamic Binding的疑问:为何调用的是子类的print方法?

为什么父类引用指向子类对象时,调用的是子类的print方法?

这个问题其实是面向对象语言里**动态绑定(运行时绑定)**的核心体现,我用具体代码和通俗的逻辑给你拆解清楚:

先看一段典型的示例代码:

// 定义父类
class Parent {
    public void print() {
        System.out.println("我是父类的print方法");
    }
}

// 子类继承父类,并重写print方法
class Child extends Parent {
    @Override
    public void print() {
        System.out.println("我是子类的print方法");
    }
}

// 测试逻辑
public class TestBinding {
    public static void main(String[] args) {
        Parent obj = new Child(); // 父类类型的引用,指向子类对象
        obj.print(); // 实际输出:我是子类的print方法
    }
}

核心原因:运行时才确定执行的方法

编译阶段,编译器只知道obj的引用类型是Parent,它只会检查Parent类里有没有print()方法——确认存在后,编译就通过了。但到了运行阶段,JVM会去识别obj实际指向的对象类型(这里是Child对象),然后优先调用子类中重写的print()方法。

这就是动态绑定的本质:方法的调用不是由引用类型决定的,而是由对象的实际类型决定的。

动态绑定生效的3个前提

要触发这个机制,必须满足以下条件:

  • 方法是实例方法(静态方法不行,静态方法属于类,是编译时绑定,和对象无关)
  • 子类确实重写了父类的该方法(方法名、参数列表、返回值必须完全匹配,@Override注解可以帮你校验重写是否合法)
  • 必须是父类引用指向子类对象(这是多态场景的典型写法)

为什么要设计动态绑定?

这是面向对象中多态的核心价值——让代码更灵活、易扩展。比如你可以写一个通用方法:

public static void executePrint(Parent p) {
    p.print();
}

不管你传入的是Parent对象,还是Child、GrandChild(如果有更深层的子类),这个方法都能自动调用对应对象的print()方法,不用针对每个子类写单独的判断逻辑。

举个反例:如果是静态方法,就不会有动态绑定效果。比如:

class Parent {
    public static void staticPrint() {
        System.out.println("父类静态方法");
    }
}

class Child extends Parent {
    public static void staticPrint() {
        System.out.println("子类静态方法");
    }
}

// 调用测试
Parent obj = new Child();
obj.staticPrint(); // 输出:父类静态方法

因为静态方法属于类,编译时就确定了调用哪个类的方法,和对象的实际类型完全无关。

内容的提问来源于stack exchange,提问作者Alberto Artoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:50:54