乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      把new、virtual、override說(shuō)透

       獨(dú)孤求財(cái) 2012-04-09

      把new、virtual、override說(shuō)透

      分類: C#基礎(chǔ) 7897人閱讀 評(píng)論(43) 收藏 舉報(bào)

      我們先看下面一段程序:

      1.     /// <summary>
      2.     /// 父類
      3. /// 作者:周公
      4. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      5. /// 日期:2008-09-01
      6.     /// </summary>
      7.     public class Father
      8.     {
      9.         public void Run0()
      10.         {
      11.             Console.WriteLine("Father.Run0");
      12.         }
      13.      }
      14.     /// <summary>
      15. /// 子類
      16. /// 作者:周公
      17. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      18. /// 日期:2008-09-01
      19.     /// </summary>
      20.     public class Son:Father
      21.     {
      22.         public void Run0()
      23.         {
      24.             Console.WriteLine("Son.Run0");
      25.         }
      26. }
      27. class Program
      28.     {
      29.         static void Main(string[] args)
      30.         {
      31.         Father[] fatherList = new Father[2];
      32.             fatherList[0] = new Father();
      33.             fatherList[1] = new Son();
      34.             fatherList[0].Run0();
      35.             fatherList[1].Run0();
      36.     }
      37. }

       

      程序的運(yùn)行結(jié)果是:
      Father.Run0

      Father.Run0

       

      稍微細(xì)心的朋友可能發(fā)現(xiàn)在Son類的Run0方法下面有一段棕色的波浪線,當(dāng)我們把鼠標(biāo)放到該下劃線上時(shí),會(huì)看到下面的提示編譯程序時(shí)在程序的“輸出”窗口也能看到這個(gè)警告

      MethodDemo.Son.Run0()”隱藏了繼承的成員“MethodDemo.Father.Run0()”。如果是有意隱藏,請(qǐng)使用關(guān)鍵字new。

      如圖:

       

      然后我們?cè)賮?lái)第二個(gè)版本的Run方法,我們稱之為Run1(),,與第一個(gè)版本的區(qū)別是在子類的同名同參(方法名相同,參數(shù)個(gè)數(shù)和參數(shù)順序相同,下同)方法前面加上了一個(gè)new關(guān)鍵字,代碼如下:

      1.     /// <summary>
      2.     /// 父類
      3.  /// 作者:周公
      4. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      5. /// 日期:2008-09-01    
      6. /// </summary>
      7.     public class Father
      8.     {
      9.         public void Run1()
      10.         {
      11.             Console.WriteLine("Father.Run1");
      12.         }
      13.      }
      14.     /// <summary>
      15. /// 子類
      16. /// 作者:周公
      17. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      18. /// 日期:2008-09-01
      19.     /// </summary>
      20.     public class Son:Father
      21.     {
      22.         public new void Run1()
      23.         {
      24.             Console.WriteLine("Son.Run1");
      25.         }
      26. }
      27. class Program
      28.     {
      29.         static void Main(string[] args)
      30.         {
      31.         Father[] fatherList = new Father[2];
      32.             fatherList[0] = new Father();
      33.             fatherList[1] = new Son();
      34.             fatherList[0].Run1();
      35.             fatherList[1].Run1();
      36.     }
      37. }

      運(yùn)行結(jié)果如下:

      Father.Run1

      Father.Run1

       

      我們發(fā)現(xiàn)加上new關(guān)鍵字之后,程序的運(yùn)行結(jié)果沒(méi)有發(fā)生改變。也就是在C#中,如果在子類中有與父類同名同參的方法時(shí),C#會(huì)隱式幫你在子類的方法前面添加一個(gè)new關(guān)鍵字。

       

      我們?cè)賹?xiě)第三個(gè)版本的Run方法,即Run2(),與第一個(gè)版本不同的是父類的Run2()方面前面加了一個(gè)virtual關(guān)鍵字,表示這是一個(gè)虛方法,子類的Run2()除了與第一個(gè)版本號(hào)不同之外(Run0()改成Run2())沒(méi)有什么不同。

      程序代碼如下:

      1.     /// <summary>
      2.     /// 父類
      3. /// 作者:周公
      4. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      5. /// 日期:2008-09-01
      6.     /// </summary>
      7.     public class Father
      8.     {
      9.         public virtual void Run2()
      10.         {
      11.             Console.WriteLine("Father.Run2");
      12.         }
      13.      }
      14.     /// <summary>
      15. /// 子類
      16. /// 作者:周公
      17. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      18. /// 日期:2008-09-01
      19.     /// </summary>
      20.     public class Son:Father
      21.     {
      22.         public void Run2()
      23.         {
      24.             Console.WriteLine("Son.Run2");
      25.         }
      26. }
      27. class Program
      28.     {
      29.         static void Main(string[] args)
      30.         {
      31.         Father[] fatherList = new Father[2];
      32.             fatherList[0] = new Father();
      33.             fatherList[1] = new Son();
      34.             fatherList[0].Run2();
      35.             fatherList[1].Run2();
      36.     }
      37. }

      我們看看程序的運(yùn)行效果:

      Father.Run2

      Father.Run2

       

      程序運(yùn)行效果與第一個(gè)仍然沒(méi)有什么區(qū)別,不過(guò)這次子類(Son)的Run2()方法又出現(xiàn)了與Run方法的第一個(gè)版本(Run0())一樣的警告:“MethodDemo.Son.Run2()”將隱藏繼承的成員“MethodDemo.Father.Run2()”。若要使當(dāng)前成員重寫(xiě)該實(shí)現(xiàn),請(qǐng)?zhí)砑雨P(guān)鍵字override。否則,添加關(guān)鍵字new。

       

      我們?cè)賹?xiě)第四個(gè)版本的Run方法,我們稱之為Run3(),這次父類中Run3()的修飾符與第三個(gè)版本相比沒(méi)有變化(依然是virtual,虛方法),而子類Son中的Run3()方法與第三個(gè)版本相比多了一個(gè)override修飾符(這次我們熟悉的那個(gè)棕色的波浪線警告沒(méi)有了)。代碼如下:

      1.     /// <summary>
      2.     /// 父類
      3. /// 作者:周公
      4. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      5. /// 日期:2008-09-01
      6.     /// </summary>
      7.     public class Father
      8.     {
      9.         public virtual void Run3()
      10.         {
      11.             Console.WriteLine("Father.Run3");
      12.         }
      13.      }
      14.     /// <summary>
      15. /// 子類
      16. /// 作者:周公
      17. /// 首發(fā)地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx
      18. /// 日期:2008-09-01
      19.     /// </summary>
      20.     public class Son:Father
      21.     {
      22.         public override void Run3()
      23.         {
      24.             Console.WriteLine("Son.Run3");
      25.         }
      26. }
      27. class Program
      28.     {
      29.         static void Main(string[] args)
      30.         {
      31.         Father[] fatherList = new Father[2];
      32.             fatherList[0] = new Father();
      33.             fatherList[1] = new Son();
      34.             fatherList[0].Run3();
      35.             fatherList[1].Run3();
      36.     }
      37. }

      程序的運(yùn)行結(jié)果如下:

      Father.Run3

      Son.Run3

       

      這次我們發(fā)現(xiàn)程序的運(yùn)行結(jié)果與前面三次不一樣了,這次盡管我們聲明的對(duì)象類型都是Father類(Father數(shù)組裝的自然都是Father類型的引用),但是因?yàn)閷?shí)例化數(shù)組中第二個(gè)元素的時(shí)候調(diào)用了Son類的構(gòu)造函數(shù),也就是實(shí)例化了一個(gè)Father類的子類(我們知道子類可以當(dāng)作父類來(lái)看待,他們之間是is a的關(guān)系,反之則不行),也就是說(shuō)fatherList數(shù)組中的第二個(gè)元素的引用類型是Father類型,但它的實(shí)例類型確實(shí)Son類型。而在運(yùn)行的時(shí)候,并不是根據(jù)我們的引用類型(引用類型是Father類型的)去調(diào)用該引用類型的方法,而是調(diào)用該引用類型所指向的實(shí)例的方法。

       

      為什么會(huì)發(fā)生這些現(xiàn)象呢?這里要提到兩個(gè)概念:早綁定(early binding)和晚綁定(Late binding)。這個(gè)術(shù)語(yǔ)出現(xiàn)在存在繼承關(guān)系的基類和派生類中,它們同時(shí)定義了一個(gè)同名同參的方法。

      早綁定:在編譯的時(shí)候就已經(jīng)確定了將來(lái)程序運(yùn)行基類或是派生類的哪個(gè)方法。在編譯代碼的時(shí)候根據(jù)引用類型就決定了運(yùn)行該引用類型中定義的方法,即基類的方法。這種方法運(yùn)行效率高。

      晚綁定:只有在運(yùn)行的時(shí)候才能決定運(yùn)行基類或者派生類中的哪個(gè)方法。運(yùn)行的時(shí)候?qū)⒏鶕?jù)該實(shí)際類型而不是引用類型來(lái)調(diào)用相關(guān)方法,即取決于我們new了什么樣對(duì)象。也就是即使我們new一個(gè)Father類的子類Son的實(shí)例,而不管我們是用Father類的引用指向這個(gè)Son的實(shí)例,方法調(diào)用的時(shí)候依然是調(diào)用Son的方法,而不是Father類的同名方法。

      如我們上面所見(jiàn),為了實(shí)現(xiàn)晚綁定,C#引入了兩個(gè)關(guān)鍵詞virtual和override。和Java中不同,Java中一切方法都是虛方法,也就是在運(yùn)行的時(shí)候,JVM會(huì)自動(dòng)檢測(cè)該引用的類型與實(shí)際類型是否一致(無(wú)論如何,該引用類型與實(shí)際類型之間存在著相等或者繼承關(guān)系,這樣才滿足is a的關(guān)系),如果一致執(zhí)行該類型中定義的方法;如果不一致則會(huì)檢查該引用的實(shí)際類型是否具有同名同參方法,如果有則運(yùn)行該實(shí)際類型的同名同參方法。這樣會(huì)帶來(lái)一個(gè)問(wèn)題:每次運(yùn)行的時(shí)候都會(huì)進(jìn)行類型檢查,這樣會(huì)帶來(lái)一定的性能消耗。而在C#中一切方法如果沒(méi)有顯示指明,都是非虛的。對(duì)于非虛的方法,CLR運(yùn)行的時(shí)候并不會(huì)進(jìn)行類型檢查,而是直接運(yùn)行該引用的類型中所定義的方法,即使這個(gè)引用所指向的實(shí)際類型是該引用類型的派生類,并且在派生類中存在著同名同參的方法,也不會(huì)運(yùn)行派生類中定義的方法。這時(shí),派生類中的方法隱藏了基類中的方法。

      但是如果在基類中顯示聲明方法為虛方法,那么CLR在運(yùn)行的時(shí)候會(huì)進(jìn)行類型檢查,如果發(fā)現(xiàn)引用類型和實(shí)際的對(duì)象類型不一致,就會(huì)檢查派生類中是否覆蓋(override)了基類中的方法,如果是,則會(huì)運(yùn)行派生類中的方法,而不是引用類型中的方法。

       

      有興趣的朋友還可以看看本人的另一篇文章:《談?wù)凜#中的三個(gè)關(guān)鍵詞new , virtual , override》

       

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多