您的位置:首页 >如何通过静态方法的重定义 Hiding 实战区分其与方法重写的本质差异
发布于2026-05-20 阅读(0)
扫一扫,手机访问
在Ja va的世界里,多态无疑是面向对象编程最迷人的特性之一。它让代码拥有了“动态”的灵魂,但这份灵动也带来了不少困惑。其中,一个经典且高频的混淆点,就出现在静态方法与实例方法的重写行为上。很多开发者会误以为两者遵循相同的规则,实则不然,这背后是编译期与运行时的根本差异。
简单来说,静态方法不能被重写,只能被“隐藏”(Hiding);而实例方法才能被真正重写(Overriding)。理解这一点,关键在于抓住方法绑定的时机和调用依据。
静态方法不能被重写,只能被隐藏;因其绑定发生在编译期,依赖引用的声明类型而非对象的实际类型,不参与虚方法表和运行时多态机制。

当子类定义了一个与父类签名完全相同的静态方法(同名、同参数、同返回类型)时,会发生什么?它并不会像实例方法那样覆盖父类方法,而是将父类的静态方法“隐藏”起来。这意味着:
父类名.方法名()的方式显式调用它。相比之下,当子类重写一个非 private、非 static 的实例方法时,情况就完全不同了:
理论说再多,不如一行代码来得直观。假设我们有父类 A 和子类 B extends A,它们都定义了静态方法 test() 和实例方法 run()。
A a = new B(); a.test(); // 输出 A.test() —— 静态方法:看左边 a 是 A 类型 a.run(); // 输出 B.run() —— 实例方法:看右边 new B(),真正重写生效
看到了吗?同样的引用a,调用静态方法时执行了父类版本,调用实例方法时却执行了子类版本。这就是“声明类型”与“实际类型”在两种方法调用上的分野。
如果再换一种写法:B b = new B(); b.test();,那么输出就会是B.test(),因为此时的声明类型是B。这再次印证了,静态方法的调用路径不依赖于对象本身,只依赖于引用的声明类型。
其实,private方法和static方法在“不可被重写”这一点上,本质原因是相通的:它们都不参与运行时的动态分派机制。
所以说,子类虽然可以定义与父类private或static方法同名的方法,但这只是一种形式上的“定义”,并非面向对象意义上的“重写”或“覆盖”。理解了这个底层机制,下次再遇到类似问题,你就能一眼看穿本质了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8