static方法能否被重写

  在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写(Override)。方法重写又称方法覆盖。
  在《Java编程思想》中提及到:

  “覆盖”只有在某方法是基类的接口的一部分时才会出现。即,必须能将一个对象向上转型为它的基本类型并调用相同的方法。

  那么,我们便可以据此来对static方法能否被重写的问题进行验证:
  
例1:   

class StaticSuper{
    public static String staticGet(){
        return "Base staticGet()";
    }
    public String dynamicGet(){
        return "Base dynamicGet()";
    }
}

class StaticSub extends StaticSuper{
    public static String staticGet(){
        return "Derived staticGet()";
    }
    public String dynamicGet(){
        return "Derived dynamicGet()";
    }
}

public class StaticPolyMorphism {
    public static void main(String[] args) {
        StaticSuper sup = new StaticSub();
        System.out.println(sup.staticGet());
        System.out.println(sup.dynamicGet());
    }
}

  在例1中,如果基类StaticSuper中的static方法staticGet()在子类StaticSub中被重写了,那么sup.staticGet()返回的结果应该是“Derived staticGet()”,实际上结果是如何呢?运行程序后,我们看到输出是:
  
  Base staticGet()
  Derived dynamicGet() 
  
  这说明,非静态方法dynamicGet()的确在子类中被重写了,而静态方法staticGet()却没有。对于这一点,我们也可以通过在子类方法上添加@Overide注解进行验证:
  override.png-18.6kB
  
  如图所示,在子类中的静态方法staticGet()上添加@Override注解会导致编译报错:The method staticGet() of type StaticSub must override or implement a supertype method(StaticSub类的staticGet()方法必须覆盖或者实现一个父型的方法),而非静态方法dynamicGet()则无此报错信息,这也就印证了我们上面的推论。其实,在Java中,如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。正如同《Java编程思想》中所说:“一旦你了解了多态机制,可能就会认为所有事物都可以多态地发生。然而,只有普通方法的调用可以是多态的。”这也很好地理解了,为什么在Java中,static方法和final方法(private方法属于final方法)是前期绑定,而其他所有的方法都是后期绑定了。