Java動態綁定 靜態綁定

http://blog.sina.com.cn/s/blog_59c9412d0100g7is.html 

運行時綁定也叫動態綁定,它是一種調用對象方法的機制。Java調用對象方法時,一般採用運行時綁定機制。
1.Java的方法調用過程
編譯器查看對象的聲明類型和方法名(對象變量的聲明類型)。通過聲明類型找到方法列表。
編譯器查看調用方法時提供的參數類型。
如果方法是private、static、final或者構造器,編譯器就可以確定調用那個方法。這是靜態綁定。
如果不是上述情況,就要使用運行時(動態)綁定。在程序運行時,採用動態綁定意味着:虛擬機將調用對象實際類型所限定的方法。
2.運行時(動態)綁定的過程
虛擬機提取對象的實際類型的方法表;
虛擬機搜索方法簽名;
調用方法。
注意,這裏說的是對象的實際類型。即在多態的情況下,虛擬機可以找到所運行對象的真正類型。
3.在向上轉型情況下的動態綁定示例

Code:
  1.  public class Father {    
  2.      public void method() {    
  3.         System.out.println(" 父類方法,對象類型:" + this.getClass());    
  4.      }    
  5.  }    
  6.   
  7.  public class Son extends Father {    
  8.     public static void main(String[] args) {    
  9.        Father sample = new Son();// 向上轉型    
  10.        sample.method();    
  11.     }    
  12.  }      

結果1:

父類方法,對象類型:class samples.Son

這個結果沒有疑問,聲明的是父類的引用(句柄),但準確的調用了子類的對象,調用method,在子類中沒有該方法,所以去父類中尋找到並調用之。

現在修改子類,重寫(override)method方法。

Java代碼
Code:
  1. public class Son extends Father {    
  2.     public void method() {    
  3.        System.out.println(" 子類方法,對象類型:" + this.getClass());    
  4.    }    
  5.        
  6.  public static void main(String[] args) {    
  7.        Father sample = new Son();// 向上轉型    
  8.       sample.method();    
  9.     }    
  10. }    

結果2:

子類方法,對象類型:class samples.Son

這個結果也是意料之中的。調用method時,在子類中尋找到了該方法,所以直接調用之。

4.靜態綁定成員變量

在處理Java類中的成員變量時,並不是採用運行時綁定,而是一般意義上的靜態綁定。所以在向上轉型的情況下,對象的方法可以“找到”子類,而對象的屬性 還是父類的屬性。

現在再進一步變化,在父類和子類中同時定義和賦值同名的成員變量name,並試圖輸出該變量的值。

Java代碼
Code:
  1. public class Father {    
  2.      protected String name=" 父親屬性";    
  3.         
  4.      public void method() {    
  5.         System.out.println(" 父類方法,對象類型:" + this.getClass());    
  6.      }    
  7.  }    
  8.       
  9.  public class Son extends Father {    
  10.      protected String name=" 兒子屬性";    
  11.         
  12.    public void method() {    
  13.         System.out.println(" 子類方法,對象類型:" + this.getClass());    
  14.      }    
  15.         
  16.      public static void main(String[] args) {    
  17.         Father sample = new Son();// 向上轉型    
  18.         System.out.println(" 調用的成員:"+sample.name);    
  19.      }    
  20.  }    

結果3:

調用的成員:父親屬性

這個結果表明,子類的對象(由父類的引用handle)調用到的是父類的成員變量。所以必須明確,運行時(動態)綁定針對的範疇只是對象的方法。

現在試圖調用子類的成員變量name,該怎麼做?最簡單的辦法是將該成員變量封裝成方法getter形式。

Java代碼
Code:
  1. public class Father {    
  2.      protected String name = " 父親屬性";    
  3.       
  4.      public String getName() {    
  5.         return name;    
  6.     }    
  7.       
  8.      public void method() {    
  9.         System.out.println(" 父類方法,對象類型:" + this.getClass());    
  10.      }    
  11.  }    
  12.       
  13.  public class Son extends Father {    
  14.      protected String name=" 兒子屬性";    
  15.         
  16.      public String getName() {    
  17.        return name;    
  18.      }    
  19.         
  20.      public void method() {    
  21.         System.out.println(" 子類方法,對象類型:" + this.getClass());    
  22.      }    
  23.         
  24.      public static void main(String[] args) {    
  25.         Father sample = new Son();// 向上轉型    
  26.         System.out.println(" 調用的成員:"+sample.getName());    
  27.      }    
  28.  }    

結果4:

調用的成員:兒子屬性


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章