熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

認識.NET中的虛函數

2022-06-13   來源: .NET編程 

  面向對象的程序設計有三大要素封裝繼承和多態虛函數是多態的重要組成部分同時又在類的繼承關系中有著很多變化本文討論NET中對虛函數的支持
  首先我們通過一個例子來看看虛函數的普通用法

  class CA {
    public virtual void Foo() {
      ConsoleWriteLine(CAFoo);
    }
  }
  
  class CB : CA {
    public override void Foo() {
      ConsoleWriteLine(CBFoo);
    }
}
  
class Test {
    public static void InvokeFoo(CA ca)  {
      caFoo();
    }
    public static void Main()  {
      InvokeFoo(new CB());
    }
}

  輸出結果

  CBFoo

  在這個例子中盡管在調用InvokeFoo()的時候CB被轉換成CA但是當執行caFoo的時候仍然調用了CB的Foo因為ca此時指向的是一個CB類型的對象這種調用模式我們稱之為運行時綁定因為在編譯InvokeFoo時編譯器無法獲取參數ca的真實類型只有在運行的時候才能根據ca的真實類型決定調用哪一個函數

  在這個例子中兩個關鍵字值得我們注意首先是virtual他告訴編譯器當前函數需要運行時綁定其次是override他告訴編譯器我要覆蓋基類中的Foo()

  看到這裡可能讀者會對兩個問題持有疑惑

  [問題]: 不用virtual結果如何?

  [問題]: 不用override結果如何?

  讀者不妨自己動手修改上例嘗試這兩個關鍵字的不同組合看看輸出的結果如何在這裡我僅給出組合條件和其輸出結果

  序號 基類(CA)中是否有virtual 子類(CB)中是否有override 輸出
是 是 CBFoo
是 否 CAFoo
否 是 編譯錯誤
否 否 CAFoo

  我希望通過對這組實驗結果的解釋交待一些NET中虛函數的相關概念

  運行時綁定僅體現在虛函數中因此在試驗輸出的結果是CAFoo因為Foo沒有被申明為virtual在編譯階段已經把caFoo綁定到CAFoo

  Override只能用於虛函數中當子類繼承基類他便擁有了基類所有的函數Override修飾的函數將替換基類原來的函數否則子類會新增加一個函數並同時保留基類中的函數 下面的這個例子很好的說明了這個問題

  class CA {
    public virtual void Foo() {
      ConsoleWriteLine(CAFoo);
    }
  }
  
  class CB : CA {
    public override void Foo()  {
      ConsoleWriteLine(CBFoo);
    }
  }
  
  class CC : CA  {
    public new void Foo()  {
      ConsoleWriteLine(CCFoo);
    }
  }
  
  class Test  {
    public static void Main()  {
      ConsoleWriteLine(typeof(CB)GetMethods()Length);  // 輸出
      ConsoleWriteLine(typeof(CC)GetMethods()Length); // 輸出
    }
  }

  這段程序輸出CB和CC的函數個數CB的個函數中個來自於SysetmObject剩下的一個就是FooCC中多了一個函數因為使用了new (如果不使用new也是相同的結果因為C#編譯器默認使用new但不顯示指明new會給出一個警告)說明了CCFoo是一個不同於CAFoo的虛函數


From:http://tw.wingwit.com/Article/program/net/201311/11712.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.