静态分派和动态分派

public class StaticDispatch {    
    public void sayHello(Human guy) {
        System.out.println("hello, guy!");
    }    
    public void sayHello(Man guy) {
        System.out.println("hello, man!");
    }    
    public void sayHello(Women guy) {
        System.out.println("hello, women!");
    }    
    public static void main(String[] args) {        
        Human man = new Man();        
        Human women = new Women();        
        StaticDispatch sd = new StaticDispatch();        
        sd.sayHello(man);        
        sd.sayHello(women);
    }
}

class Human {    
}

class Man extends Human {    
}

class Women extends Human {    
}

输出结果:

hello, guy!

hello, guy!

我们把Human称为变量的静态类型,Man称为变量的实际类型。

其中,变量的静态类型和动态类型在程序中都可以发生变化,而区别是变量的静态类型是在编译阶段就可知的,但是动态类型要在运行期才可以确定,编译器在编译的时候并不知道变量的实际类型是什么。

代码中,由于方法的接受者已经确定是StaticDispatch的实例sd了,所以最终调用的是哪个重载版本也就取决于传入参数的类型了。

实际上,虚拟机(应该说是编译器)在重载时时通过参数的静态类型来当判定依据的,而且静态类型在编译期就可知,所以编译器在编译阶段就可根据静态类型来判定究竟使用哪个重载版本。于是对于例子中的两个方法的调用都是以Human为参数的版本。

Java中,所有以静态类型来定位方法执行版本的分派动作,都称为静态分派。

动态分派和多态的另外一个重要体现有很大的关联:重写(override)。

例子如下:

public class DynamicDispatch {
    public static void main(String[] args) {        
        Human man = new Man();
        Human women = new Women();
        
        man.sayHello();
        women.sayHello();
        
        man = new Women();
        man.sayHello();
    }
}

abstract class Human {
    protected abstract void sayHello();
}
class Man extends Human {
    @Override
    protected void sayHello() {
        System.out.println("hello man!");
    }    
}
class Women extends Human {
    @Override
    protected void sayHello() {
        System.out.println("hello women!");
    }}

变量的实际类型是在运行期确定的,重写方法的调用也是根据实际类型来调用的。我们把这种在运行期根据实际类型来确定方法执行版本的分派动作,称为动态分派。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值