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中的重寫是動態分派。就是在運行期間肯定接受者的實例類型,將類方法中的符號引用解析到了不一樣的直接引用上,這就是方法重寫的本質。程序

相關文章
相關標籤/搜索