一.结论
- java中静态字段和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏。
也就是说在子类构造与父类同名同参的静态方法不是重写了父类的方法,而是重新的定义了一个方法,不能在此方法上面加@Override,否则报错。 - 如果想要调用父类的静态方法和字段,直接通过父类名.方法或变量名完成。
- 多态之所以能够实现依赖于继承、接口和重写、重载(继承和重写最为关键,静态方法无法重写,所以实现不了多态,而非静态方法可以被重写,所以可以实现多态。
- 静态字段和非静态字段可以被继承,但是无法被重写,所以也实现不了多态。
- 重写后子类的方法优先于父类,但是静态方法不能够被重写,而是被隐藏,所以没有优先级之分,即在哪个类里调用就调用哪个类的静态方法。
- java中类的方法池中都有一个隐含的参数this,他表示本对象的引用 但是static方法是没有这个隐含参数的,因为static方法和类的实例无关,它只在类装载的时候初始化。
二.例子
class A{
private String a;
static int x = 1;
int y = 2;
public A(String a){
this.a = a;
}
public static void study(){ System.out.println("A.study"); }
public void joy(){ System.out.println("A.joy"); }
public void print(){
System.out.println(this.getClass());
this.study();
this.joy();
System.out.println("a---" + a );
}
}
class B extends A{
private String b;
public B(String a,String b){
super(a);
this.b = b;
}
public static void study(){ System.out.println("B.study");}
@Override
public void joy(){ System.out.println("B.joy"); }
@Override
public void print(){
super.print();
System.out.println(this.getClass());
this.study();
this.joy();
System.out.println("b---" + b);
}
}
class C extends B{
private String c;
public C(String a,String b,String c){
super(a,b);
this.c = c;
}
public static void study(){System.out.println("C.study"); }
@Override
public void joy(){ System.out.println("c.joy"); }
@Override
public void print(){
super.print();
System.out.println(this.getClass());
this.study();
this.joy();
System.out.println("c---" + c);
}
}
class D extends A{
public D(String a) {
super(a);
}
}
public class thisDemo1 {
public static void main(String[] args) {
B a = new C("aa","bb","cc"); //1
a.print(); //2
System.out.println("-----------------");
a.study(); //3
System.out.println("-----------------");
D d = new D("d"); //4
D.study(); //5
d.study(); //6
d.joy(); //7
System.out.println("-----------------");
System.out.println("D.x = " + D.x); //8
System.out.println("d.y = " + d.y); //9
}
}
结果:
class 实验.C
A.study
c.joy
a---aa
class 实验.C
B.study
c.joy
b---bb
class 实验.C
C.study
c.joy
c---cc
-----------------
B.study
-----------------
A.study
A.study
A.joy
-----------------
D.x = 1
d.y = 2
分析:
- 将B类型的a引用指向一个C类型的对象,用于实现多态
- ①调用a对象的print()方法,因为多态,所以调用的其实是C类的print()方法,①调用a对象的print()方法,因为多态,所以调用的其实是C类的print()方法,
②super.print();
调用父类B类的print()方法,又碰到super.print();即调用A类的print()方法
③System.out.println(this.getClass());
进入到A类的print()方法,打印this指针指的对象的类型,因为创建(new)的对象为C类型,而a只是一个B类型的引用,所有,输出结果为C类型。
④this.study();
由于study()是静态方法,静态方法与实例无关,所以调用的还是本类(A类)的study()方法。
⑤this.joy();
由于this()是非静态方法,实现多态,即执行的是C类的joy()方法。
⑥System.out.println(“a—” + a);
打印a类中的私有类型a字段。
⑦执行完A类的print方法,再返回B类中,执行super.print();以后的方法,之后再进入C类中,执行super.print();以后的方法。执行过程与①~⑥类似,就不再赘述。 - 由于study()是静态方法,所以执行的是本类(B类)的方法。
- new一个D类型的对象d。
- D类继承于A类,里面只有构造方法,所以执行的是A类的study()方法。
- 执行的是A类的study()方法,证明了静态方法可以被继承。
- 执行的是A类的joy()方法,与6进行对比,证明了非静态方法可以被继承。
- 输出的是A类型的静态字段值,证明了静态字段可以被继承。
- 输出的是A类型的静态字段值,与8进行对比,证明了非静态字段可以被继承。
参考:https://zhidao.baidu.com/question/87437962.html