关于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
相关产品推荐
相关产品推荐

