C# new vs override

Muhammad Maisam Abbas 2024年2月16日
  1. C# 中的 new 關鍵字
  2. C# 中的 override 關鍵字
C# new vs override

本教程將討論 C# 中的 newoverride 關鍵字之間的區別。

C# 中的 new 關鍵字

new 關鍵字 在 C# 中非常常見。傳統上,它可以用在三個不同的地方:運算子、修飾符和約束。

new 關鍵字的第一個也是最流行的用法是作為運算子在 C# 中建立類物件並呼叫它們的類建構函式。使用 new 關鍵字,在堆疊中建立諸如 intfloat 之類的值型別物件,並在堆中建立諸如使用者定義類之類的引用型別物件。

使用 new 關鍵字作為運算子時要記住的一些事情是:它僅將記憶體分配給物件,不會破壞以前依賴於同一範圍的任何記憶體,並且我們不能覆蓋 C# 中的 new 關鍵字。

其次,當使用 new 關鍵字作為修飾符時,它隱藏了從派生類繼承的基類成員。前面的語句意味著不是覆蓋或宣告該繼承類成員的新定義,而是用 new 關鍵字替換基類中該成員的先前定義。

new 關鍵字的第三次使用與前兩次相比相對不常見。在使用 new 關鍵字作為約束時,我們指定泛型型別必須具有不帶附加引數的公共建構函式。

這種方法的缺點是我們不能將它與抽象型別一起使用。

在本教程中,我們將使用 new 關鍵字作為修飾符,以對派生類隱藏基類的定義。在 C# 中,編譯器預設隱式隱藏任何繼承函式的定義。

下面的程式碼片段演示瞭如何使用 new 關鍵字從派生類中顯式隱藏繼承函式的定義。

public class BaseClass {
  public virtual void fun() {
    Console.WriteLine("Base class");
  }
}

public class DerivedClass : BaseClass {
  public new void fun() { Console.WriteLine("Derived class");
}
public static void Main(string[] args) {
  BaseClass b = new BaseClass();
  DerivedClass d = new DerivedClass();
  BaseClass bd = new DerivedClass();
  b.fun();
  d.fun();
  bd.fun();
}
}

輸出:

Base class
Derived class
Base class

前兩個物件的輸出非常簡單; BaseClass 物件 b 引用了基類中的 fun() 函式,DerivedClass 物件 d 引用了派生類中的 fun() 函式。

當我們將派生類的引用分配給基類 bd 的物件並呼叫 fun() 函式時,會發生一件非常有趣的事情。基類中的 fun() 函式這次仍然執行。

這是因為在基類中實現 fun() 函式對派生類是隱藏的。

無需使用 new 關鍵字也可以實現相同的目標。下面的程式碼片段展示了我們如何在不使用 new 關鍵字的情況下實現相同的目標。

public class BaseClass {
  public virtual void fun() {
    Console.WriteLine("Base class");
  }
}

public class DerivedClass : BaseClass {
  public void fun() {
    Console.WriteLine("Derived class");
  }
  public static void Main(string[] args) {
    BaseClass b = new BaseClass();
    DerivedClass d = new DerivedClass();
    BaseClass bd = new DerivedClass();
    b.fun();
    d.fun();
    bd.fun();
  }
}

輸出:

Base class
Derived class
Base class

請注意,輸出與以前的方法相同。這裡唯一的區別是,這一次,我們得到一個編譯器警告,說要顯式隱藏類成員,請使用 new 關鍵字。

沒有新關鍵字的編譯器警告

C# 中的 override 關鍵字

在 C# 中,override 修飾符 擴充套件了從基類繼承的方法。override 關鍵字提供了從基類繼承的 virtual 方法的新實現。

這裡要注意的一件事是我們不能使用 override 關鍵字來擴充套件非虛擬或靜態方法。基類中的函式必須是虛擬的、抽象的或被另一個超類覆蓋。

在我們之前示例的上下文中,以下程式碼片段顯示了我們如何使用 override 修飾符來擴充套件從基類繼承的 virtual 函式的功能。

public class BaseClass {
  public virtual void fun() {
    Console.WriteLine("Base class");
  }
}

public class DerivedClass : BaseClass {
  public override void fun() {
    Console.WriteLine("Derived class");
  }
  public static void Main(string[] args) {
    BaseClass b = new BaseClass();
    DerivedClass d = new DerivedClass();
    BaseClass bd = new DerivedClass();
    b.fun();
    d.fun();
    bd.fun();
  }
}

輸出:

Base class
Derived class
Derived class

前兩個物件的輸出非常簡單; BaseClass 物件 b 引用了基類中的 fun() 函式,DerivedClass 物件 d 引用了派生類中的 fun() 函式。

當我們將派生類的引用分配給基類 bd 的物件並呼叫 fun() 函式時,與 new 關鍵字的真正區別出現了。與前兩個示例不同,這一次,派生類的 fun() 函式被呼叫。

override 關鍵字用於向其父物件顯示虛擬函式的子實現,而 new 關鍵字用於對其父類物件隱藏子實現。

Muhammad Maisam Abbas avatar Muhammad Maisam Abbas avatar

Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.

LinkedIn

相關文章 - Csharp Keyword