
本文深入解析为何子类中定义的私有方法(如student.getinfo())不会覆盖父类同名私有方法,以及为何继承而来的public方法(如printperson())在运行时仍调用父类的私有方法,而非子类中看似“同名可用”的私有方法。
本文深入解析为何子类中定义的私有方法(如student.getinfo())不会覆盖父类同名私有方法,以及为何继承而来的public方法(如printperson())在运行时仍调用父类的私有方法,而非子类中看似“同名可用”的私有方法。
在Java中,private 方法具有严格的访问边界:它仅对声明它的直接所在类可见,既不可被继承,也不可被重写(override),甚至在子类中都不可见——哪怕方法签名完全相同。
回到示例代码:
class Person {
private String getInfo() { return "Person"; }
public void printPerson() { System.out.println(getInfo()); }
}
class Student extends Person {
private String getInfo() { return "Student"; } // ✅ 编译通过,但这是全新方法!
}
关键点在于:Student.getInfo() 并非重写了 Person.getInfo(),而是在Student类中重新声明了一个独立的、仅属于Student的私有方法。由于 private 方法不具备多态性,JVM在编译期就已将 Person.printPerson() 中的 getInfo() 绑定到 Person 类内部的版本(即静态绑定/早期绑定)。因此,无论 printPerson() 是通过 new Person() 还是 new Student() 调用,其中的 getInfo() 永远指向 Person 类自己的私有实现。
? 验证技巧:若你本意是希望子类提供不同行为,请将
getInfo()改为protected或public,并显式添加@Override注解:class Person { protected String getInfo() { return "Person"; } public void printPerson() { System.out.println(getInfo()); } } class Student extends Person { @Override // ✅ 编译器将校验是否真正重写成功 protected String getInfo() { return "Student"; } }此时
new Student().printPerson()将输出"Student"—— 因为getInfo()变为可重写、可动态分派的实例方法。
⚠️ 注意事项:
-
private方法不参与继承链,子类中同名private方法是独立存在、互不影响的两个方法; - 多态(动态绑定)仅适用于
public/protected/包级(非private)的实例方法; -
@Override注解是极佳的防御性编程实践:若误以为private方法可被重写,添加该注解会立即触发编译错误,避免逻辑误解; - 若需子类定制行为,应优先设计为
protected模板方法,或采用组合+策略模式替代深度继承。
总结:printPerson() 虽然被继承到 Student 类中,但它内部调用的 getInfo() 是在 Person 类作用域内解析的,而 Student 的私有 getInfo() 对 Person 完全不可见——这正是封装与静态绑定共同决定的语言语义,而非访问权限的“遗漏”。理解这一点,是掌握Java继承与多态本质的关键一步。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











