以下是原文翻译成繁體中文的Markdown格式:

C# - Polymorphism

# C# - 多形性:初學者指南

你好,有志的程式設計師們!今天,我們將要深入探索面向對象程式設計中最引人入勝的概念之一:多形性。不要被這個大詞嚇到 - 到了這個教學的結尾,你將會像專家一樣使用多形性!

## 什麼是 多形性?

在我們開始之前,讓我們來拆解這個花俏的詞語。"Poly" 意味著許多,而 "morph" 意味著形狀。所以,多形性就是關於有許多形狀。在程式設計中,它是對象能夠根據上下文採取不同形狀並有不同的行為的能力。

想像你是一個變形者(這會有多酷?)你可以是人類,一隻貓,甚至是龍!這就是多形性允許我們的代碼做到的 - 根據需要採取不同的形狀。

在C#中,我們有两种主要的多形性類型:

1. 靜態多形性(也稱為編譯時多形性)
2. 動態多形性(也稱為運行時多形性)

讓我們詳細探討每一種。

## 靜態多形性

靜態多形性發生在編譯器在編譯時就知道要調用哪個方法。這就像在離開房子之前決定要穿什麼衣服 - 你提前就知道!

### 函數重載

靜態多形性最常見的形式是函數重載。這是當你有多个同名方法但參數不同時發生。

讓我們看一個例子:

```csharp
public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public double Add(double a, double b)
    {
        return a + b;
    }

    public string Add(string a, string b)
    {
        return a + b;
    }
}

在這個例子中,我們有三個 Add 方法:

  1. 一個添加兩個整數
  2. 一個添加兩個雙精度浮點數
  3. 一個連接兩個字符串

現在,讓我們使用我們的 Calculator

Calculator calc = new Calculator();

int sum1 = calc.Add(5, 3);            // 使用整數版本
double sum2 = calc.Add(3.14, 2.86);   // 使用雙精度浮點數版本
string sum3 = calc.Add("Hello, ", "World!"); // 使用字符串版本

Console.WriteLine(sum1);  // 輸出: 8
Console.WriteLine(sum2);  // 輸出: 6
Console.WriteLine(sum3);  // 輸出: Hello, World!

編譯器根據我們傳遞的參數類型知道要調用哪個 Add 方法。這就像擁有一把瑞士軍刀 - 一個工具,多種用途!

動態多形性

動態多形性是當關於調用哪個方法的決策在運行時做出。這就像在舞台上即興表演 - 你在當下決定要做什麼!

動態多形性的關鍵是使用 virtual 和 override 關鍵字。讓我們看一個例子:

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("這個動物發出聲音");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("這條狗吠叫:汪!汪!");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("這隻貓喵喵叫:喵!喵!");
    }
}

在這個例子中,我們有一個基類 Animal 和一個 virtual MakeSound 方法。DogCat 類從 Animal 繼承並覆寫 MakeSound 方法。

現在,讓我們看看動態多形性在行動:

Animal myAnimal = new Animal();
Animal myDog = new Dog();
Animal myCat = new Cat();

myAnimal.MakeSound();  // 輸出: 這個動物發出聲音
myDog.MakeSound();     // 輸出: 這條狗吠叫:汪!汪!
myCat.MakeSound();     // 輸出: 這隻貓喵喵叫:喵!喵!

即使 myDogmyCat 被聲明為 Animal 類型,它們仍然使用它們自己的 MakeSound 方法。這就是動態多形性的魔力!

多形性的力量

多形性讓我們能夠撰寫更靈活且可重用的代碼。想像你正在創建一個有不同角色類型的遊戲。每個角色可能會有不同的移動方式:

public class Character
{
    public virtual void Move()
    {
        Console.WriteLine("這個角色移動。");
    }
}

public class Warrior : Character
{
    public override void Move()
    {
        Console.WriteLine("這個戰士衝鋒!");
    }
}

public class Mage : Character
{
    public override void Move()
    {
        Console.WriteLine("這個法師傳送。");
    }
}

public class Rogue : Character
{
    public override void Move()
    {
        Console.WriteLine("這個盜賊靜靜地潛行。");
    }
}

現在,我們可以有一個角色列表並讓它們全部移動:

List<Character> characters = new List<Character>
{
    new Warrior(),
    new Mage(),
    new Rogue()
};

foreach (var character in characters)
{
    character.Move();
}

// 輸出:
// 這個戰士衝鋒!
// 這個法師傳送。
// 這個盜賊靜靜地潛行。

這就是多形性的美麗之處 - 我們可以將所有這些不同的角色當作 Character 對象對待,但它們每個都有自己獨特的方式行為。

多形性方法的總結

這裡是我們討論過的多形性方法的快速參考表:

方法 類型 描述
函數重載 靜態 多個同名方法但參數不同
Virtual/Override 動態 基類定義 virtual 方法,派生類覆寫它們

結論

恭喜你!你剛剛踏入了多形性的世界。記住,像學習任何新技能一樣,掌握多形性需要練習。如果它立即沒有引起你的共鳴 - 不要氣餒 - 繼續編程,繼續嘗試,很快你將會像真正的編程變形者一樣塑造你的程序!

當我們結束時,這裡有一個編程笑話給你:為什麼程式設計師喜歡暗色模式?因為光會吸引蟲子!

祝編程愉快,未來的多形性大師們!

Credits: Image by storyset