我们知道在JAVA中可以通过overRide来增强或减弱父类的方法和行为,但覆写是针对非静态方法的,不能针对静态方法(也叫类方法),为什么呢?看一下下面的例子:
View Code public class OverRideTepublic static void main(String[] args){ Father father=new Son(); father.print1(); father.print2(); } } class Father{ public static void print1(){ System.out.println("我是父类静态方法"); } public void print2(){ System.out.println("我是父类非静态方法"); } } class Son extends Father{ public static void print1(){ System.out.println("我是子类静态方法"); } public void print2(){ System.out.println("我是子类非静态方法"); } }1 public class OverRideTest {2 3 public static void main(String[] args){4 Father father=new Son();5 father.print1();6 father.print2();7 }8 9 } 10 class Father{ 11 public static void print1(){ 12 System.out.println("我是父类静态方法"); 13 } 14 public void print2(){ 15 System.out.println("我是父类非静态方法"); 16 } 17 } 18 class Son extends Father{ 19 public static void print1(){ 20 System.out.println("我是子类静态方法"); 21 } 22 23 public void print2(){ 24 System.out.println("我是子类非静态方法"); 25 } 26 }
看程序子类son覆写了父类father中的print1(),print2()方法,按道理来说应该都是执行覆写后的方法,然而
运行之后结果:
我是父类静态方法
我是子类非静态方法
分析原因:
son的两个覆写区别仅仅在是否有static,每个实例对象都有两个类型,一个是表面类型,一个是实际类型,表面类型是在声明时得到的,实际类型是对象产生时的类型,例子中,Father是表面类型,Son是实际类型,对于非静态方法而言,是根据对象的实际类型来执行;而对于静态方法则比较特别,首先静态方法不依赖于实例对象,通过类名来访问,其次,可以通过对象访问静态方法,如果是通过对象访问,JVM是通过对象的表面类型来找到静态方法的入口,因而执行Father中的静态方法。