Modifiers: virtual, override, new, abstract, sealed, internal

  • internal
    • 聲明類、類成員、接口或接口成員具有內部可見性。
    • internal 修飾符使類、接口或成員僅在當前包中可見。 當前包之外的代碼不能訪問 internal 成員。只有在同一程序集的文件中,內部類型或成員纔是可訪問的
    • 在全局範圍內,internal 修飾符與 public 修飾符相同。
    • 不能將 internal 修飾符與其他任何可見性修飾符(publicprivate 或 protected)組合。 可見性修飾符相對於它們的定義範圍。
  • sealed
    • 當對一個類應用 sealed 修飾符時,此修飾符會阻止其他類從該類繼承。
    • 在重寫基類中的虛方法或虛屬性的方法或屬性上使用 sealed 修飾符。 這將使您能夠允許類從您的類繼承,並防止它們重寫特定的虛方法或虛屬性。
    • 當應用於方法或屬性時,sealed 修飾符必須始終與 override 一起使用。
  • abstract
    • abstract 修飾符指示所修飾的內容缺少實現或未完全實現。 abstract 修飾符可用於類、方法、屬性、索引器和事件。 在類聲明中使用 abstract 修飾符以指示某個類只能是其他類的基類。 標記爲抽象或包含在抽象類中的成員必須通過從抽象類派生的類來實現。
    • 抽象類不能實例化。
    • 抽象類可以包含抽象方法和抽象訪問器。
    • 不能用 sealed(C# 參考) 修飾符修飾抽象類,因爲這兩個修飾符的含義是相反的。 採用 sealed 修飾符的類無法繼承,而 abstract 修飾符要求對類進行繼承。
    • 從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實際實現。
    • 抽象方法是隱式的虛方法(virtual)。
    • 只允許在抽象類中使用抽象方法聲明。
    • 在抽象方法聲明中使用 static 或 virtual 修飾符是錯誤的。
    • 實現接口的抽象類可以將接口方法映射到抽象方法上。
  • new
    • 在用作聲明修飾符時,new 關鍵字可以顯式隱藏從基類繼承的成員。 隱藏繼承的成員時,該成員的派生版本將替換基類版本。 雖然可以不使用 new 修飾符來隱藏成員,但將收到編譯器警告。 如果使用 new 來顯式隱藏成員,將禁止此警告。
    • 對同一成員同時使用 new 和 override 是錯誤的做法,因爲這兩個修飾符的含義互斥。 new 修飾符會用同樣的名稱創建一個新成員並使原始成員變爲隱藏。 override 修飾符會擴展繼承成員的實現。
  • override
    • 要擴展或修改繼承的方法、屬性、索引器或事件的抽象實現或虛實現,必須使用 override 修飾符。
    • override 方法提供從基類繼承的成員的新實現。重寫的基方法必須與 override 方法具有相同的簽名。
    • 不能重寫非虛方法或靜態方法。 重寫的基方法必須是 virtualabstract 或 override 的。
    • override 聲明不能更改 virtual 方法的可訪問性。 override 方法和 virtual 方法必須具有相同的訪問級別修飾符
    • 您不能使用 newstatic 或 virtual 修飾符來修改 override 方法。
    • 在 Derived 的一個實例中調用 method 時,C# 編譯器將首先嚐試使該調用與最初在 Derived 上聲明的 method 版本兼容。 重寫方法不被視爲是在類上進行聲明的,而是在基類上聲明的方法的新實現。 僅當 C# 編譯器無法將方法調用與 Derived 上的原始方法匹配時,它才嘗試將該調用與具有相同名稱和兼容參數的重寫方法匹配。
  • virtual
    • virtual 關鍵字用於修飾方法、屬性、索引器或事件聲明,並使它們可以在派生類中被重寫。
    • 默認情況下,方法是非虛擬的。 不能重寫非虛方法。
    • virtual 修飾符不能與 staticabstract, private 或 override 修飾符一起使用。
Examples:
public abstract class A
   {
      public abstract void Do();
      public virtual void DrawLine() { Console.WriteLine("A:DrawLine"); }
      public virtual void DrawPoint() { Console.WriteLine("A:DrawPoint"); }
      public virtual void DoWork() { Console.WriteLine("A:DoWork"); }
   }

   public class B : A
   {
      public override void Do() { Console.WriteLine("B:DO"); }
      public new void DrawLine() { Console.WriteLine("B:DrawLine"); }
      public override void DrawPoint() { Console.WriteLine("B:DrawPoint"); }
      public override void DoWork() { Console.WriteLine("B:DoWork"); }
   }

   public class C : B
   {
      public sealed override void DoWork() { Console.WriteLine("C:DoWork"); }
   }

   public class D : C
   {
      // Attempting to override DoWork causes compiler error CS0239.
      //public override void DoWork() {}
      public new void DoWork() { Console.WriteLine("D:DoWork"); }
   }

   // Only accessible within the same assembly
   internal class MyInternalClass
   {
      public string Value { get; set; }
   }

   //public sealed class MySealedClass { }
   //public class Derived : MySealedClass { } // error CS0509: '': cannot derive from sealed type

   interface I
   {
      void M();
   }
   abstract class AC : I
   {
      public abstract void M();
   }

   public class Base
   {
      public virtual void DoWork(int param) { Console.WriteLine("Base:DoWork(int)"); }
   }

   public class Derived : Base
   {
      public override void DoWork(int param) { Console.WriteLine("Derived:DoWork(int)"); }
      public void DoWork(double param) { Console.WriteLine("Derived:DoWork(double)"); }
   }

   A a = new B();
   a.DrawLine(); // output A:DrawLine
   a.DrawPoint(); // output B:DrawPoint
   a.Do(); // output B:DO

   D d = new D();
   d.DoWork(); // output D:DoWork
   C c = (C)d;
   c.DoWork(); // output C:DoWork
   B b = (B)d;
   b.DoWork(); // output C:DoWork

   int val = 5;
   Derived der = new Derived();
   der.DoWork(val);  // Calls DoWork(double).
   ((Base)der).DoWork(val);  // Calls DoWork(int) on Derived.


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