class F {
public static void main(String[] args) {
Son s=new Son();
s.show();
}
}
class Father {
public void show(){
show2();
}
public void show2(){
System.out.println("父亲");
}
}
class Son extends Father {
public void show2() {
System.out.println("儿子");
}
}
想知道这个s.show()为什么调用的是儿子这个show2()方法,而不是父亲这个show2()方法?
yi因为你没覆盖或者重写
这种情况如果你用子类引用调用就是子类
用父类引用调用就是父类
PS:照理来说是这样.不一样的语言环境和编译器有可能有不同处理.
总的来说就是:语法错误!
简单来说,父类方法被子类重写覆盖掉时,想调用到父类的方法必须要加上super关键字;
即使是强转为father类也依然改变不了show2方法被子类重写的结果,
只有通过重写show方法里使用super来调用show2方法,结果才会是父类的
1 class Father { 2 public void show(){ 3 show2(); 4 } 5 public void show2(){ 6 System.out.println("父亲"); 7 } 8 } 9 class Son extends Father { 10 1./* 11 public void show(){ 12 super.show2(); 13 } 14 */ 15 public void show2() { 16 System.out.println("儿子"); 17 } 18 } 19 20 class test { 21 public static void main(String[] args) { 22 Son s=new Son(); 23 2./* 24 Father f=(Father)s; 25 f.show(); 26 */ 27 s.show(); 28 } 29 }
这就是java的多态,它总是执行子类重写的方法,实际原理是:
不要看着代码是调用父类的show,然后调用父类的show2。这样就是静态的多态,编译期就确定了(c++好像是这种)。
java的多态是动态的,意味执行哪个方法,在运行时,它会判断是子类还是父类对象在调用。
细节原理是:
java的方法调用有个默认的参数,就是对象本身,这个是编译器帮你做了,比如你的
Son s=new Son();
s.show();
实际是:s.show(s); ===>>>> show2(s)
虚拟机判断是儿子在调用方法,就当然执行儿子的show2
里面这个参数就上面说的用来做动态判断执行子类还是父类的方法的多态动态性。
调用方法是由对象去调用的,所以在Father中执行show2方法的时候实际是由Son的对象去调用的。而在Son中有show2方法就调用了Son的方法。如果没有找到匹配的方法,那么会继续向上找。