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

C# 面向對象核心:多態完整解析與虛擬方法、重寫、動態綁定

     編輯:關於C#

多態定義

多態:同一操作作用於不同物件時,表現出不同行為。「一個介面,多種實作」。

三大支柱

  1. 繼承:子類別繼承父類別
  2. 虛擬方法:父類別用 virtual 標記可被覆寫的方法
  3. 重寫:子類別用 override 提供專屬實作

經典範例


public abstract class Animal
{
    public string Name { get; set; }
    protected Animal(string name) => Name = name;

    // 虛擬方法:提供預設實作,允許子類別重寫
    public virtual void Shout()
    {
        Console.WriteLine($"我是動物:{Name}");
    }

    // 抽象方法:強制子類別實作,無預設行為
    public abstract void Move();
}

public class Cat : Animal
{
    public Cat(string name) : base(name) { }

    public override void Shout() // 重寫:完全取代父類實作
    {
        Console.WriteLine($"喵~ 我是 {Name}");
    }

    public override void Move() => Console.WriteLine($"{Name} 靜悄悄地走");
}

public class Dog : Animal
{
    public Dog(string name) : base(name) { }

    public override void Shout()
    {
        Console.WriteLine($"汪!我是 {Name}");
    }

    public override void Move() => Console.WriteLine($"{Name} 搖著尾巴跑");
}

public class Bird : Animal
{
    public Bird(string name) : base(name) { }
    // 不重寫 Shout(),使用父類預設實作
    public override void Move() => Console.WriteLine($"{Name} 飛上藍天");
}

多態演示


var animals = new Animal[]
{
    new Cat("小花"),
    new Dog("大黃"),
    new Bird("小鳥")
};

foreach (var animal in animals)
{
    animal.Shout(); // 動態綁定:執行實際物件類型的方法
    animal.Move();
    Console.WriteLine();
}

/* 輸出:
喵~ 我是 小花
小花 靜悄悄地走

汪!我是 大黃
大黃 搖著尾巴跑

我是動物:小鳥  (Bird 未重寫 Shout,使用父類虛擬方法)
小鳥 飛上藍天
*/

關鍵概念深度解析

virtual vs abstract

特性virtualabstract
方法主體有預設實作無實作 (分號結尾)
子類別重寫可選強制
類別修飾詞可用於非抽象類別僅限 abstract 類別
呼叫基底實作base.Method()無基底實作

動態綁定機制

  • 編譯期:根據宣告型別檢查方法是否存在
  • 執行期:根據實際物件型別尋找最衍生的實作 (虛方法表 v-table)
  • 只有 virtual/abstract/override 方法參與動態綁定
  • 非虛方法 (預設) 永遠靜態綁定

多態的必要條件

  1. 宣告型別為基底類別/介面 (Animal animal = new Cat())
  2. 實際物件為衍生類別
  3. 呼叫虛擬/抽象/重寫方法

進階:密封與新增


public class Base
{
    public virtual void Method() { }
}

public class Derived : Base
{
    // 密封:禁止進一步重寫
    public sealed override void Method() { }
}

public class Further : Derived
{
    // 錯誤:無法重寫 sealed 方法
    // public override void Method() { } 
    
    // 新增:隱藏基底方法 (非多態,靜態綁定)
    public new void Method() { }
}

介面多態


public interface IShape
{
    double Area();
}

public class Circle : IShape
{
    public double Radius { get; set; }
    public double Area() => Math.PI * Radius * Radius;
}

public class Rectangle : IShape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public double Area() => Width * Height;
}

// 使用
IShape[] shapes = { new Circle { Radius = 2 }, new Rectangle { Width = 3, Height = 4 } };
foreach (var s in shapes) Console.WriteLine(s.Area());

最佳實踐

  1. 優先用介面定義契約,實作類別隱藏細節
  2. 預設方法標記 virtual,明確開放擴充點
  3. 重寫必加 override,編譯器驗證簽名一致
  4. 避免深層繼承樹,組合優於繼承
  5. 封裝變化:將易變行為抽出為虛擬方法/策略模式
  6. Liskov 替換原則:子類別必須能無縫替換父類別

常見誤區

誤區正確認知
多態 = 繼承多態需要繼承,但繼承不一定產生多態 (需虛方法)
所有方法都是多態的只有 virtual/abstract/override 方法
父類別參考只能呼叫父類別方法父類別參考呼叫虛方法會執行子類別實作
new 關鍵字實現多態new 是隱藏 (靜態綁定),非多態

多態是物件導向設計靈活性的核心,善用虛擬方法與介面,讓系統擁有「開放擴充、封閉修改」的擴展能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved