C#中virtual,override,new的區別是什麼

virtual
  用於父類中,聲明某方法可以重寫,該方法不能是static;
override(覆蓋繼承)
  用於子類中,重寫父類中用virtual/override/abstract關鍵字聲明的方法;
new(隱藏繼承)
  用於子類中,可修飾父類中有或無virtual聲明的方法;
  如果在父類中有與父類同名同參的方法時,C#會隱式在子類前添加一個new關鍵字。

【區別】override與new
  當將一個子類實例賦值給父類實例,在子類實例與父類實例中分別調用該方法時:使用override修飾的都將調用子類方法,而使用new修飾的會分別調用子類方法和父類方法。
  New和Override這兩個關鍵字是互斥的。不可以同時使用。


【區別】virtual與abstract
  virtual:用於父類中聲明該方法可被重寫。
  abstract:只能用在抽象類中聲明抽象方法,本身不能實現任何功能(因此必須在子類中override),不能實例化。
  兩者除了在子類中同樣可以用override重寫這個相同點之外,沒有其他關係。
 

 

-------------------------------------------------------------------------------------------------------------------

C#支持單繼承,說到繼承就不得不說new,virtual和override這三個關鍵詞,靈活正確的使用這三個關鍵詞,可以使程序結構更加清晰,代碼重用性更高。
    

      以下是msdn中對new,virtual和override的定義:

      使用 new 修飾符顯式隱藏從基類繼承的成員。若要隱藏繼承的成員,請使用相同名稱在派生類中聲明該成員,並用 new 修飾符修飾它。
      virtual 關鍵字用於修改方法或屬性的聲明,在這種情況下,方法或屬性被稱作虛擬成員。虛擬成員的實現可由派生類中的重寫成員更改。調用虛方法時,將爲重寫成員檢查該對象的運行時類型。將調用大部分派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員。默認情況下,方法是非虛擬的。不能重寫非虛方法。
      virtual 修飾符不能將與以下修飾符一起使用:
      static    abstract    override
      使用 override 修飾符來修改方法、屬性、索引器或事件。重寫方法提供從基類繼承的成員的新實現。由重寫聲明重寫的方法稱爲重寫基方法。重寫基方法必須與重寫方法具有相同的簽名。不能重寫非虛方法或靜態方法。重寫基方法必須是虛擬的、抽象的或重寫的。
      重寫聲明不能更改虛方法的可訪問性。重寫方法和虛方法必須具有相同的訪問級修飾符。
    
      override不能使用下列修飾符修改重寫方法:
      new   static    virtual   abstract
      重寫屬性聲明必須指定與繼承屬性完全相同的訪問修飾符、類型和名稱,並且重寫屬性必須是虛擬的、抽象的或重寫的。
     
可以稍微歸納一下:
      1. 對於基類中說明爲虛的方法則必須在派生類中new或者override(注:對於基類的虛方法,雖然你在派生類中即不new也不override,但系統還是會提示你添關鍵字。否則系統將視其爲隱藏。我們的意思是一樣的,但總覺得明明確確寫上關鍵字還是好些)。

      2. 如果用基類指針指向派生類對象的方式,動態匹配的源動力是virtual,而new和override都會阻止這種向下尋求匹配的行爲,所以要使虛函數的性質得已保持下去,就要隱藏基類的虛方法,即在派生類中隱藏基類虛方法時,同時加以virtual關鍵字,使在多層次繼承中能夠調用到對象自身的版本。注:如 public new virtual  方法名()

      3.在多層次繼承中,三個關鍵字使用次序有限定。
    new沒有使用前提,即不管是普通方法、虛方法還是重寫了的方法。

    virtual的使用,在它的基類不能有函數簽名相同的方法,否則系統將提示添加new,即隱藏基類中的方法。virtual一般只出現一次,除非要在子類中隱藏父類的虛方法。
override的使用是爲了重寫基類虛方法。
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
           
            B b = new B();
            A a = b;
            B c = (B)a;
            OK(b);
            
            
        }
        public static void OK(A a)
        {
            a.Soft();
        }
    }
    class A
    {
        private string p_name;
        private string p_sex;
        public A()
        {
            this.p_name = "李世民";
            this.p_sex = "男";
        }
        public A(string str_name,string str_sex) 
        {
            this.p_name = str_name;
            this.p_sex = str_sex;
        }
        public void M()
        {
            Console.WriteLine("姓名:"+this.p_name);
            Console.WriteLine("性別:"+this.p_sex);
        }
        public virtual void Soft()
        {
            Console.WriteLine("我是A類裏面的soft方法");
        }
        public void F()
        {
            Console.WriteLine("我是A類裏的F方法");
        }
    }
    class B :A{
        private string 朝代;
        public B():base()
        {
            this.朝代 = "大唐王朝";
        }
        public B(string s_name, string s_sex, string cd)
            : base(s_name, s_sex)
        {
            this.朝代 = cd;
        }
        public new void M()
        {
            base.M();
            Console.WriteLine("朝代:"+this.朝代);
            
        }
        public override void Soft()
        {
            Console.WriteLine("我是B類裏的Soft方法");
        }
        public new void F()
        {
            Console.WriteLine("我是B類裏的F方法");
        }

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章