父类静态方法可以重写吗?

2,958 阅读2分钟
原文链接: mp.weixin.qq.com

重写(Override)作为Java的特性之一,经常被作为面试问题。

比较坑的一个问题是,子类能否重写父类的静态方法?答案当然是可以的。但是重写之后会发生什么,是否调用子类静态方法会执行子类的逻辑,这才是坑所在的地方。

重写

回顾一下Override的定义,重写是对父类允许访问的方法的实现逻辑进行重新编写。但是不能改变方法的返回值和参数内容。从它的特点上来说,重写允许子类对象拥有自己的实现逻辑。从这个角度来说,重写静态方法是不允许的。

重写静态方法会发生什么?

虽然原则上不允许重写静态方法,但是,编译器是不会报错的那么重写之后会发生什么呢?来看这么一段代码

class SuperClass{  public static void staticMethod(){    System.out.println("SuperClass: inside staticMethod");  }  public static void main(String []args){    SuperClass superClassWithSuperCons = new SuperClass();    SuperClass childClassWithSubCons = new ChildClass();    ChildClass childClassWithChildCons = new ChildClass();    superClassWithSuperCons.staticMethod();    childClassWithSubCons.staticMethod();    childClassWithChildCons.staticMethod();  }}class ChildClass extends SuperClass{//overriding the static method  public static void staticMethod(){    System.out.println("ChildClass: inside staticMethod");  }}

输出结果是

SuperClass: inside staticMethodSuperClass: inside staticMethodChildClass: inside staticMethod

第二行输出说明,即使重写了静态方法,执行的还是父类的逻辑。这也就证明了,静态方法是在编译时使用了编译类信息,进行静态绑定的。它和对象无关,而和类有关。

总结

对于静态方法,我们不应该尝试去重写,而且调用时应该以类进行调用,而不是对象进行调用。重写,说的是根据运行时的对象类型来决定调用哪个方法,而不是编译时类型。静态方法是属于类的方法,在编译阶段就确定了。因此即使重写了也没意义。如果这样说的不够明白,可以回想平时开发中我们经常用的工厂模式,或者面向接口编程。我们经常会用父类来声明一个对象,而对象是在运行时才确定的,这就是运行时重写的意义所在。而对于静态方法的调用,虽然Java允许通过对象来调用,但只是为了开发方便,正确的姿势是通过类来调用。