Java子类对象调用重写方法的执行规则及与构造器重载的关系
问题解答
核心结论
两个Test1类对象调用calculate()方法时,全部执行的是子类重写后的版本,该判定逻辑和构造器重载没有任何关联。
方法调用的判定规则
Java 中针对非静态、非私有、非 final 修饰的实例方法,调用时遵循动态绑定(动态分派)机制:方法执行的版本只由调用方法的对象的实际运行时类型决定,和对象的创建方式、引用类型(只要实际类型是子类)都无关。
你代码中创建的myshape1和myshape2都是通过new Test1(...)生成的,运行时实际类型都是Test1类,因此两个对象调用calculate()时,都会优先匹配Test1类中重写的实现,永远不会触发父类Shape的calculate()方法。
构造器重载的作用
构造器重载的唯一作用是提供多种初始化对象成员变量的逻辑,不会改变创建出的对象的实际类型,更不会影响后续方法调用的分派逻辑:
- 调用
Test1(double l, double h)构造器时,通过super(l)将父类的length和breadth都赋值为l,子类的height赋值为传入的h - 调用
Test1(double l, double b, double h)构造器时,通过super(l,b)将父类的length赋值为l、breadth赋值为b,子类的height赋值为传入的h
两个构造器只是初始化成员变量的数值不同,最终生成的对象都是Test1类型,因此不会对calculate()方法的选择逻辑产生任何影响。
补充说明
只有两种情况会触发父类Shape的calculate()方法:
- 实际创建的是
Shape类的实例,比如Shape shape = new Shape(2,3); shape.calculate(); - 在子类的方法实现中,显式通过
super.calculate()调用父类的方法实现
内容的提问来源于stack exchange,提问作者Arin Paliwal
相关产品推荐
相关产品推荐

