为何Java代码中第4行仅输出"B move"?
问题解析:第4行输出不符合预期的原因
核心区别在于方法重写(Override)和方法重载(Overload)的本质不同,以及Java方法调用的静态绑定与动态绑定规则。
1. 关键概念梳理
- 重写:子类定义的方法与父类方法的方法名、参数列表(类型、数量、顺序)、返回值(协变)完全一致,运行时会根据对象的实际类型动态调用子类实现。
- 重载:同一类(或继承体系中)的方法名相同,但参数列表不同,属于不同的方法,编译时就会根据调用时的参数类型确定具体调用哪个方法。
2. move方法调用逻辑分析(第4行:c.move("Test"))
- 变量
c的声明类型是A,编译器会先在A类中查找匹配方法:A存在move(Object o)。 - 传入的
String参数是Object的子类,编译器会将其向上转型为Object,绑定到A.move(Object)方法。 - 运行时动态绑定:
C类的move(String s)是重载方法(参数列表与父类move(Object)不同),并没有重写move(Object),因此实际调用的是B类中重写的move(Object),仅输出B move,不会触发C的move(String)。
3. keep方法调用逻辑对比(第5行:c.keep("Test"))
- 变量
c的声明类型是A,编译器在A类中找到完全匹配的keep(String s)方法,直接绑定。 - 运行时动态绑定:
C类的keep(String s)与A的keep(String s)方法名、参数列表完全一致,属于重写,因此实际调用C的keep(String)。 C.keep(String)中super.keep(s)调用的是父类B的keep(String),但B并未重写A的keep(String)(B的keep(Object o)是重载),因此最终调用A的keep(String)输出A keep,随后执行C自身逻辑输出C keep。
总结
第4行的C.move(String)是重载方法,并非对父类move(Object)的重写,因此通过A类型引用调用时,只会触发父类中被重写的move(Object);而第5行的C.keep(String)是对A.keep(String)的重写,所以会触发子类的完整实现。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

