155个建议笔记建议33:不要覆写静态方法

我们知道在JAVA中可以通过overRide来增强或减弱父类的方法和行为,但覆写是针对非静态方法的,不能针对静态方法(也叫类方法),为什么呢?看一下下面的例子:

View Code
public class OverRideTe

 public 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中的静态方法。

原文地址:https://www.cnblogs.com/yuwenfeng/p/3069152.html