虛函數無敵解釋

來源:互聯網
上載者:User

助於理解。。。

虛擬函數(virtual)
  使用物件導向的開發過程就是在不斷的抽象事物的過程,我們的目標就是抽象出一個緊內聚,低偶合,易於維護和擴充的模型.但是在抽象過程中我們會發現很多事物的特徵不清楚,或者很容易發生變動,怎麼辦呢?比如飛禽都有飛這個動作,但是對於不同的鳥類它的飛的動作動方式是不同的,有的要滑行,有的要顫抖翅膀, 雖然都是飛但千差萬別,在我們抽象的模型中不可能一個個都考慮到,怎麼為以後留下好的擴充,怎麼來處理子類的前差萬別?比如我現在又要抽象一個類"鶴", 它也有飛禽的特徵,我可以簡單的繼承"飛禽",而不去修改現有的代碼,可以很容易的擴充系統
  物件導向的概念中引入了虛擬函數. 就是在父類中把子類中共同的,易於變化或者不清楚的特徵抽取出來,作為子類需要去重新實現的操作(override),我們可以稱做"熱點".還是上面的例子
  class 飛禽
  { 
    private void Shape ;    //注意private訪問修訂符,Shape是不會被子類繼承的!
    public string Wing ;    //翅膀
    public string Feather ; //羽毛  
    public virtual boolean Fly() {} ;  //飛翔. 定義的虛擬函數, 這是一個熱點
  }
 
  class 麻雀 : 飛禽    //麻雀從飛禽繼承而來
  {
    public boolean CanSpeaking; //申明了麻雀自己的特徵.
    public override boolean Fly() {...} ;    //重載飛翔動作,實現自己的飛翔
  }

  class  鶴 : 飛禽  //鶴從飛禽繼承而來
  {
   
    public override void Fly() {...} ;    //重載實現鶴的飛翔
  }
 
  //如何來使用虛擬函數,這裡同時也是一個多態的例子.
  //打鳥
  void ShootBird(Bird : 飛禽)  //注意這裡申明傳入一個"飛禽"類,而不是具體的"鳥類". 好處是以後不管出現多少種鳥類,只要是從飛禽繼承下來的,都照打不誤:)
  {
    if( Bird.fly())
    {
      ....
      開始打鳥...
      ...
    }
  }
 
  static void main()
  {
     //打麻雀
     ShootBird( new 麻雀());
     //打鶴
     ShootBird( new 鶴());    
     //看到沒!都是打鳥的過程,我這裡可以實現打任何一種鳥了,添加一行代碼而不去修改代碼
     ShootBird( new 其它的飛禽());         
     ShootBird( ...);         
  }  
-------------------------------------------- 
虛擬函數的的執行過程:   
   虛擬函數從C#的程式編譯的角度來看,它和其它一般的函數有什麼區別呢?一般函數在編譯期間就靜態編譯到了執行檔案中,在程式運行期間是不發生變化的,也就是寫死了!而虛擬函數在編譯期間是不被靜態編譯的,它是不確定的,它會根據運行時期對象執行個體來動態判斷要調用的函數,其中那個申明時定義的類叫申明類,那個執行時執行個體化的類叫執行個體類.具體的檢查的流程如下:
 a.當調用一個對象的函數時,系統會去檢查這個對象申明定義的類,即申明類
 b.然後它更據這個申明類型的定義去檢查這個函數是否虛擬函數
 c.如果有virtual關鍵字,他就認為是虛擬函數,這個時候他又去檢查執行個體類.
 d.好!找到這個執行個體類後,他再檢查這個執行個體類定義中是否重新實現了虛擬函數(通過override),如果是!好了他就不再找了,馬上執行它.
 e.如果沒有,系統又往上層父類找執行個體類的父類,直到找到一個最近重載了該虛擬函數的父類為止,然後執行該函數.
 呵呵,知道這點有什麼用呢?搞清楚這個老師的bt題目就可以拿下了.
 還是來個簡單例子說明問題
 class A
 {
   protected virtual FuncA() {Console.WriteLine("FuncA")} ;//注意virtual,表明這是一個虛擬函數
 }
 
 class B :A             //注意 B是從A類繼承,所以A是父類,B是子類
 {
   protected override FuncA(){Console.WriteLine("FuncB")} ; //注意override ,表明重新實現了虛擬函數
 }
 
 static void main()
 {
   A a ;               //定義一個a這個A類對象.這個A就是a的申明類
   A b ;               //定義一個b這個A類的對象.這個A就是b的申明類 
   a = new A() ;      //執行個體化a對象,A是這次執行個體類
   a.FuncA() ;        //開始執行FuncA. 1.先照申明類A 2.檢查是虛擬方法 3.檢查執行個體類A 4.執行執行個體類中的方法 5輸出結果 FuncA
   b = new B();     //執行個體化b對象,B是這次執行個體類
   b.FuncA() ;     //開始執行FuncA. 1.先照申明類A 2.檢查是虛擬方法 3.檢查執行個體類B  4.執行執行個體類中的方法 5輸出結果 FuncB
 }  

from:http://forum.mvpcn.net/ShowPost.asp?action=Previous&id=113

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.