動態繫結一

Diy_os發表於2015-10-27
動態繫結是java物件導向中非常重要的思想,很多java程式設計師不太清楚多型機制, 無疑會導致對多型理解程度不夠,下面透過程式碼以及在記憶體中的執行過程來分析動態繫結,如有錯誤不當之處,請讀者指正!


點選(此處)摺疊或開啟

  1. public class Animal {
  2.     
  3.     private String name;
  4.     
  5.     Animal(String name){
  6.         
  7.         this.name = name;
  8.     }
  9.    
  10.     public void enjoy(){
  11.         
  12.         System.out.println("叫聲...");
  13.     }
  14. }

  15. public class Cat extends Animal {
  16.     
  17.     private String eyesColor;
  18.     
  19.     Cat(String n,String c){
  20.             
  21.             super(n);
  22.             eyesColor = c;
  23.         }
  24.     
  25.      public void enjoy(){
  26.         
  27.          System.out.println("貓叫聲...");
  28.      }
  29.     }


  30. public class Dog extends Animal{
  31.   
  32.     private String furColor;
  33.     
  34.     Dog(String n,String c){
  35.         
  36.         super(n);
  37.         furColor = c;
  38.     }
  39.     
  40.     public void enjoy(){
  41.         
  42.         System.out.println("狗叫聲。。。");
  43.     }
  44. }

  45. public class Lady {
  46.  
  47.     private String name;
  48.     private Animal pet;
  49.     
  50.     Lady(String name,Animal pet){
  51.         
  52.         this.name = name;
  53.         this.pet = pet;
  54.     }
  55.     public void myPetEnjoy(){
  56.         
  57.         pet.enjoy();
  58.     }
  59. }

  60. public class Test {
  61.   
  62.     public static void main(String[] args){
  63.         
  64.         Cat c = new Cat("catname", "bule"); //a1
  65.         Dog d = new Dog("dogname", "black"); //b1
  66.         Lady ll = new Lady("ll", c);         //a2
  67.         Lady l2 = new Lady("12", d);         //b2
  68.         ll.myPetEnjoy();                     //a3
  69.         l2.myPetEnjoy();                     //b3
  70.     }
  71. }
上面的簡單程式碼相信很多朋友似曾相識,或者說很明白的看清程式碼意思。
首先我們還是從程式的開始類主函式分析:(關於比較細節的描述,請看之前寫過的一篇文章:http://blog.itpub.net/29876893/viewspace-1816246/,這裡不作過細分析)
a1.首先在棧中放入一Cat型別的區域性變數c,然後在堆中new出一Cat型別的物件記憶體,其中記憶體大致分為兩部分,A部分是父類Animal物件,其中有成員變數,該例name被賦值為catname,B部分是自己的成員變數eyesColor,被賦值為blue,然後棧中的Cat引用c指向堆中new出的Cat例項的全部
a2.在棧中放入Lady的引用ll,然後在堆中new出一Lady型別的物件記憶體,其中成員變數name被賦值為ll,成員變數pet被c賦值,也就是此時pet和c同時指向堆中的同一Cat例項,但是pet是Animal的引用,而Cat繼承自Animal,所以此時pet指向的是普通的Animal堆記憶體,也就是A
a3.此時用ll呼叫myPetEnjoy(),然後pet此時又呼叫enjoy(),此時你也會想,pet到底呼叫哪個enjoy?由於方法是放在程式碼區,此時程式碼區有Animal的enjoy方法程式碼段,和Cat的enjoy方法程式碼段。在A中有Animalenjoy方法的指標C指向程式碼區中的Animal的enjoy方法程式碼段,由於動態繫結機制(程式執行期間),new出誰的物件,那麼C就指向被該物件重寫的方法,此時C指向了Cat的enjoy方法程式碼段,這就是動態繫結。

同理b1,b2,b3分析如上。

那麼動態繫結(多型)給我們帶來什麼好處呢?使得程式的可擴充套件性達到了極致,如果上面Lady養了更多的寵物,那麼只需要加上所養寵物的類(新增屬性和方法),而Lady類不需要做任何的改變。
更多的動態繫結機制可以參考《thinking in java》
由於不能畫出整個過程,敘述難免空洞,感興趣的讀者可以畫圖,會變的一目瞭然。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29876893/viewspace-1816523/,如需轉載,請註明出處,否則將追究法律責任。

相關文章