Jvm(66),方法调用----动态分派调用

 

package demo.jvm.test8;

public class Demo4 {

/**

* 方法动态分派演示

*

*/

static class Human {

protected void sayHello() {

System.out.println("Human say hello"

}

 

static class Man extends Human {

protected void sayHello() {

System.out.println("man say hello"

}

}

 

static class Woman extends Human {

protected void sayHello() {

System.out.println("woman say hello"

}

}

 

public static void main(String[] args) {

Human man = new Man();

Human woman = new Woman();

man.sayHello();

woman.sayHello();

man = new Woman();

man.sayHello();

}

}

结果:

 

man say hello woman say hello woman say hello

package demo.jvm.test8;

 

public class Demo4 {

/**

* 方法动态分派演示

*

*/

static class Human {

protected void sayHello() {

System.out.println("Human say hello"

}

 

static class Man extends Human {

 

}

 

static class Woman extends Human {

 

}

 

public static void main(String[] args) {

Human man = new Man();

Human woman = new Woman();

man.sayHello();

woman.sayHello();

man = new Woman();

man.sayHello();

}

}

结果:

Human say hello

Human say hello Human say hello

由于invokevirtual指令执行的第一步就是在运行期确定接收者的实际类型,所以两次调用中的invokevirtual指令把常量池中的类方法符号引用解析到了不同的直接引用上,这个过程就是Java语言中方法重写的本质。我们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派

所以重载之和传入的变量有关系,重写却以子类为基准,越底层的子类权限越大。

注意这里首先动态分派调用的时候会先调用子类的方法,如果子类找不到则找父类,父类找不到则找父类的父类,如果到最后都找不到抛异常(一般情况下这种找不到的情况在编译器就会跑出来了。)

猜你喜欢

转载自www.cnblogs.com/qingruihappy/p/9691688.html
今日推荐