C#虛函數virtual詳解


 在面向對象編程中,有兩種截然不同的繼承方式:實現繼承和接口繼承。在實現繼承時候,在Java中,所有函數默認都是virtual的,而在C#中所有函數並不默認為virtual的,但可以在基類中通過聲明關鍵字virtual,就可以在其派生類中通過關鍵字override重寫該函數。

     重寫后的virtual函數依舊是virtual函數。由於virtual只對類中的實例函數成員有意義,所以成員字段和靜態函數都不能聲明為virtual,也不能與override和abstract一起用。C#中可以設置virtual屬性、索引器或事件,例如  

virtual string Name
{
get;
set;
}
無virtual和override關鍵字“重寫”

     如果簽名后的函數在基類中都進行了聲明,卻沒有用virtual和override關鍵字,例如:

class Base1
{
public void printMethod()
{
Console.WriteLine("base1");
}
}

class Derived1 : Base1
{
public void printMethod()
{
Console.WriteLine("derived1");
}
}
class Program
{
static void Main(string[] args)
{
Base1 base1 = new Base1();
Derived1 derived = new Derived1();

base1.printMethod();
derived.printMethod();

base1 = new Derived1();
base1.printMethod();


Console.ReadLine();
}
}


 輸出為:
          base1

          derived1

          base1

     由於方法相同,在用子類新方法編譯代碼時候,程序在應該調用哪種方法上就會有潛在的沖突,此時編譯器會發出警告,認為子類Derived1的printMethod()隱藏了父類Base1的printMethod();此時可以從新命名子類Derived1的printMethod(),這是最好的解決辦法,其次可以通過關鍵字new隱藏此方法來控制版本。

     這是所謂的無virtual和override的“重寫”其實只是隱藏。

有virtual和override關鍵字“重寫”

   在派生類中添加關鍵字virtual和override,實現對基類的重寫:

class Base1
{
public virtual void printMethod()
{
Console.WriteLine("base1");
}
}

class Derived1 : Base1
{
public override void printMethod()
{
Console.WriteLine("derived1");
}
}


class Program
{
static void Main(string[] args)
{
Base1 base1 = new Base1();
Derived1 derived = new Derived1();


base1.printMethod();
derived.printMethod();

base1 = new Derived1();
base1.printMethod();
Console.ReadLine();
}
}

 

此時,輸出的結果是:
                      base1

                     derived1

                     derived1

  在類的定義中,申明時定義的類叫申明類,執行實例化時候定義的類叫實例類。例如:

                                    Base1 base1 = new Derived1 ();其中Base1叫做申明類,而Derived1則是實例類。

  此時編譯器具體的檢查的流程如下

1、當調用函數時,系統會直接去檢查申明類,看所調用的函數是否為虛函數;

2、如果不是,那么它就直接執行該函數。如果是virtual函數,則轉去檢查對象的實例類。

3.在實例類中,若有override的函數,則執行該函數,如果沒有,則依次上溯,按照同樣步驟對父類進行檢查,知道找到第一個override了此函數的父類,然后執行該父類中的函數。(星夢《C#虛函數virtual詳解收藏》)

 由此可知,

若子類Derived1中未添加關鍵字override,則直接在base1中執行父類同名函數,此時輸出結果為:

    base1

    derived1

    base1

依次類推,若有Derived2繼承了Derived1,即:

class Derived2 : Derived1

{

public void printMethod(){

Console.WriteLine("derived2");

}

}

 

在Program類 中執行

base1 = new Derived2();

base1.printMethod();

           

則此時執行的是Derived2中override的同名函數printMethod()。
---------------------
作者:songsz123
來源:CSDN
原文:https://blog.csdn.net/songsz123/article/details/7369913
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM