java中的静态分派与动态分派

     java中的多态体如今重写和重载上,重载就属于静态分派,而重写属于动态分派。那咱们先来弄清楚什么是静态类型,什么是动态类型。例如:java

public class Son extends Father{}

Father a = new Son();

 对于以上代码:Father属于静态类型,Son属于动态类型。ide

所谓静态类型是指在程序编译期间就彻底肯定,而动态类型则是在程序运行期间才能够肯定。spa

下面,咱们来看看一个静态分派的例子:code

package fenixsoft;
public class StaticDispatch {
 //父类
 static abstract class Human{
 }
 //子类1
 static class Man extends Human{
 }
 //子类2
 static class Woman extends Human{
 }
 /*
  * 三个重载的方法
  */
 public void say(Human guy){
  System.out.println("hello,guy");
 }
 public void say(Man guy){
  System.out.println("hello,guy");
 }
 public void say(Woman guy){
  System.out.println("hello,guy");
 }
 public static void main(String[] args){
  StaticDispatch sd = new StaticDispatch();
  Human man = new Man();
  Human woman = new Woman();
  sd.say(man);
  sd.say(woman);
 }
}

这是这个例子的输出结果:对象

hello,guy
hello,guy

下面咱们来分析为何会输出这样的结果:编译器

        因为动态类型在编译期间不可知,因此编译器在编译程序时并不知道纯金的参数的实际类型是什么,也就是说,在上面的例子中,编译器不知道man和woman的实际类型,因此编译器在重载时只能经过他们的静态类型来肯定他们的类型。因此,java中重载时是经过参数的静态类型,而不是实际类型(动态类型)做为判断依据的。对于此例来讲,他们的静态类型就是Human,因此输出了这个结果。编译

 

那咱们再来看一个动态分派的例子:class

package fenixsoft;
public class DynamicDispatch {
 
 static abstract class Human{
  protected abstract void say();
 }
 
 static class Man extends Human{
  @Override
  protected void say() {
   // TODO Auto-generated method stub
   System.out.println("man,hello");
  }
  
 }
 
 static class Woman extends Human{
  @Override
  protected void say() {
   // TODO Auto-generated method stub
   System.out.println("woman,hello");
  }
  
 }
 public static void main(String[] args){
  Human man = new Man();
  Human woman = new Woman();
  man.say();
  woman.say();
 }
}

此例的输出以下:引用

man,hello
woman,hello

和静态分派相反,动态分派是经过对象的实际类型做为判断依据的。因此java中的重写是动态分派。就是在运行期间肯定接受者的实例类型,将类方法中的符号引用解析到了不一样的直接引用上,这就是方法重写的本质。程序

相关文章
相关标签/搜索