首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

深入理解 C# 多態與 new 關鍵字(上)

     編輯:關於C語言

多態的基本應用

多態是物件導向程式設計的核心特性之一。當我們希望基類定義一個通用介面,而衍生類提供具體實現時,通常使用 virtual 和 override 關鍵字。

基類定義

class Base
{
    public virtual void PrintStatus()
    {
        Console.WriteLine("public virtual void PrintStatus() in Base");
    }
}

統一處理衍生類實例

public void DisplayStatusOf(Base[] bs)
{
    foreach (Base b in bs)
    {
        b.PrintStatus(); // 多態調用
    }
}

這種設計允許我們忽略具體類型差異,以統一方式處理不同物件,正如 .NET 中 XmlReader.Create(Stream) 可接受 FileStream、MemoryStream、NetworkStream 等任何串流類型。

當衍生類「違背承諾」:new 關鍵字

若衍生類未使用 override 而是使用 new 關鍵字定義同名方法,會發生什麼?

正確覆寫

class Derived1 : Base
{
    public override void PrintStatus()
    {
        Console.WriteLine("public override void PrintStatus() in Derived1");
    }
}

使用 new 隱藏基類方法

class Derived2 : Base
{
    public new void PrintStatus()
    {
        Console.WriteLine("public new void PrintStatus() in Derived2");
    }
}

實際運行結果

Base[] bs = new Base[] { new Base(), new Derived1(), new Derived2() };
DisplayStatusOf(bs);

// 輸出:
// public virtual void PrintStatus() in Base
// public override void PrintStatus() in Derived1
// public virtual void PrintStatus() in Base  ← Derived2 未生效!

Derived2 使用 new 只是「隱藏」了基類方法,而非覆寫。透過基類參考調用時,仍會執行基類實現。

new 的本質:封印而非消滅

new 關鍵字並未刪除基類方法,只是在衍生類中遮蔽了它。我們仍可透過類型轉換「解封」訪問:

外部解封

Base d2 = new Derived2();
d2.PrintStatus(); // 輸出基類方法

內部訪問

class Derived2 : Base
{
    public new void PrintStatus()
    {
        base.PrintStatus(); // 透過 base 關鍵字調用基類版本
        Console.WriteLine("public new void PrintStatus() in Derived2");
    }
}

對於靜態成員,解封需透過類別名稱:Base.StaticMethod()。

new 的合理用途

雖然 new 容易破壞多態契約,但恰當使用可彌補基類設計不足。例如 Rockford Lhotka 在《Creating a Data Bound ListView Control》中示範如何用 new 封裝 ListView.Columns 並替換為自定義集合。

總結

  • virtual + override:實現真正的運行時多態
  • new:編譯時綁定,隱藏基類成員,不影響基類實現
  • 除非有明確設計意圖,否則優先使用 override
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved