尽量不要覆写静态方法
Updated:
我们知道在java中可以通过覆写来增强或减弱父类的方法和行为,但覆写是针对非静态方法(也叫做实例方法,只有生成实例才能调用的方法),不能针对静态方法(static修饰,也叫类方法)
来看一个例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36class Base{
public static void doSomething(){
System.out.println("我是父类的静态方法");
}
public void doAnything(){
System.out.println("我是父类的非静态方法");
}
}
class Sub extends Base{
public static void doSomething(){
System.out.println("我是子类的静态方法");
}
public void doAnything(){
System.out.println("我是子类的非静态方法");
}
}
public class Lian4 {
public static void main(String[] main){
Base base = new Sub();
base.doAnything();
base.doSomething();
}
}
输出:
我是子类的非静态方法
我是父类的静态方法
分析:
一个实例对象有两个类型: 表面类型和实际类型,表面类型是声明时的类型,实际类型是对象产生时的类型,比如我们例子,变量base的表面类型是Base,实际类型是Sub,
对于非静态方法,他是根据对象的实际类型来执行的,也就是执行了Sub类中doAnything方法,而对于静态方法来说就比较特殊了,首先静态方法不依赖与实力对象,他是通过类名访问的,其次,可以通过对象访问静态方法,如果是通过对象调用静态方法,JVM则会通过对象的表面类型来查找静态方法的入口,继而执行他。
这种类似于父类的静态方法的覆写叫做隐藏,覆写是用于非静态方法
建议:
- 尽量不覆写静态方法
- 尽量不用实例对象来访问静态方法或静态属性,
- 尽量用来类名来访问才是好习惯。