Java方法调用遵循动态绑定:编译看引用类型,运行看实际对象类型;this调用子类重写方法,super调用父类原方法;有效重写需满足签名一致、返回协变、权限不缩限等条件;static方法和字段仅隐藏,不重写。

看方法调用时的实际对象类型
Java 中方法调用遵循“动态绑定”原则:编译时看引用类型,运行时看实际对象类型。也就是说,即使变量声明为父类类型,只要它指向的是子类实例,调用被重写的方法时,执行的仍是子类中重写后的方法。
例如:
Animal a = new Dog();
a.speak(); // 输出 "汪汪汪",不是 Animal 的默认实现
这里 a 是 Animal 类型引用,但实际对象是 Dog,所以 speak() 调用的是 Dog 类重写后的方法。
区分 this 和 super 的调用目标
在子类方法内部,调用方式决定了执行哪一版逻辑:
- this.methodName():总是调用当前类(子类)中定义的方法,包括重写后版本
- super.methodName():明确跳过重写逻辑,直接调用父类中被覆盖的原始方法
常见用法是在子类重写方法中先执行父类逻辑,再添加子类特有行为:
public void speak() {
super.speak(); // 先输出“动物发出叫声”
System.out.println("汪汪汪"); // 再输出子类扩展内容
}
确认是否真为重写,而非重载或隐藏
判断是不是有效的方法重写,需同时满足以下条件:
- 方法名、参数列表(个数、类型、顺序)必须与父类完全一致
- 返回类型相同,或是父类返回类型的子类型(协变返回)
- 访问权限不能比父类更严格(如父类是 protected,子类不能是 private)
- 不能重写 private、static、final 方法
- 建议加上 @Override 注解——编译器会帮你检查签名是否匹配
注意静态方法和成员变量不参与重写
静态方法(static)和成员变量(field)的调用只看引用类型,不看实际对象,因此它们不存在“重写”,只有“隐藏”(hiding):
- 子类定义同名 static 方法,只是隐藏了父类方法;通过父类类型调用,仍执行父类版本
- 子类定义同名字段,会遮蔽(shadow)父类字段;访问哪个字段取决于变量声明类型,而非对象类型
只有实例方法才真正支持运行时多态和重写机制。

















