Contents
  1. 1. 分析:
  2. 2. 建议:

  我们知道在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
36
class 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("我是子类的静态方法");
}

@Override
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则会通过对象的表面类型来查找静态方法的入口,继而执行他。

  • 这种类似于父类的静态方法的覆写叫做隐藏,覆写是用于非静态方法

建议:

  • 尽量不覆写静态方法
  • 尽量不用实例对象来访问静态方法或静态属性,
  • 尽量用来类名来访问才是好习惯。
Contents
  1. 1. 分析:
  2. 2. 建议: