在子类中用super可以调用父类方法,这点我是清楚的。
但加入多态后,父类方法又被重写了,我就有点不清楚了。
这时候在子类重写的方法中使用super来调用父类被重写的方法,究竟调用的是父类未被重写的方法,还是已被重写的方法呢。
public class Me {
public void m(){
System.out.println("Me");
}
}
public class Ov extends Me {
public void m(){
super.m();
}
public static void main(String[] args) {
Me me = new Ov();
me.m();
}
}
输出:
Me
输出结果证明,多态也可以通过super调用父类被重写的方法
接下来修改代码
public class Me {
public void m(){
System.out.println("Me");
}
public void mm(){
m();
}
}
public class Ov extends Me {
public void m(){
System.out.println("Ov");
}
public void mm(){
super.m();
}
public static void main(String[] args) {
Me me = new Ov();
me.mm();
}
}
输出:
Me
此时父类中的mm方法被子类的mm方法重写了,而子类mm中通过super调用的是未被重写的m方法。和上一个实验结果吻合。
若把Ov类中的mm方法注释掉,输出结果就变成了“Ov”。
因为此时父类中的mm方法中的m方法被子类m方法重写了。
总结:
1.多态中,super调用的父类方法即使被重写了,调用的仍是父类的方法。
2.其他情况下,直接调用被重写的方法,调用的就是子类中的方法。哪怕是在父类的构造方法中。
3.可以让父类方法无法被重写,如加上static、private等修饰符。那么多态中,调用这样的方法(private可以通过super调用父类方法,再间接调用private方法),就会调用父类的方法。
深入:
super.method()。通过指令invokespecial,在编译时期就能确定方法调用的对象,所以我们明确知道调用的就是父类方法。
invokespecial只能调用三类方法:<init>方法;private方法;super.method()。因为这三类方法的调用对象在编译时就可以确定。