文章

第9天:繼承與多型

課程簡介

今天我們將探討物件導向程式設計中兩個重要概念:繼承多型。繼承允許一個類別從另一個類別獲得屬性和方法,而多型則讓不同類別在執行相同動作時表現出不同的行為。這些概念能提高程式的可重用性和靈活性,讓您可以構建更具彈性且易於維護的程式。


學習目標

  • 瞭解繼承的概念並應用於程式設計
  • 使用 base 關鍵字來呼叫父類別的建構函數或方法
  • 瞭解多型的基本概念及其應用
  • 使用 virtualoverride 關鍵字來實現多型

課程內容

1. 繼承(Inheritance)

繼承允許一個類別從另一個類別獲得屬性和方法。這種關係通常稱為「is-a」關係。例如,狗是一種動物,因此 Dog 類別可以從 Animal 類別繼承。

在 C# 中,使用冒號(:)表示繼承關係。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Animal
{
    public void Eat()
    {
        Console.WriteLine("This animal is eating.");
    }
}

public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("The dog is barking.");
    }
}

在這裡,Dog 類別繼承了 Animal 類別的 Eat 方法。這樣,Dog 類別的物件不僅能執行 Bark,也能執行 Eat


2. base 關鍵字

base 關鍵字用於呼叫父類別的建構函數或方法,允許子類別存取和使用父類別的屬性和方法。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Animal
{
    public string Name;

    public Animal(string name)
    {
        Name = name;
    }

    public void Eat()
    {
        Console.WriteLine(Name + " is eating.");
    }
}

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

    public void Bark()
    {
        Console.WriteLine(Name + " is barking.");
    }
}

在這裡,Dog 類別的建構函數使用 base(name) 呼叫了 Animal 類別的建構函數,從而初始化 Name 屬性。


3. 多型(Polymorphism)

多型允許在父類別和子類別之間互換使用物件。這讓您可以使用相同的方式來呼叫不同類別的對應方法,但每個類別的方法行為可能會有所不同。C# 使用 virtualoverride 關鍵字來實現多型。

使用 virtualoverride 關鍵字

父類別中的方法可以標記為 virtual,允許子類別覆寫它。子類別可以使用 override 關鍵字來改寫父類別的方法。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("The animal makes a sound.");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("The dog barks.");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("The cat meows.");
    }
}

此範例中,MakeSound 方法在 DogCat 類別中被覆寫。這樣,在程式執行時,可以根據物件的實際類型調用正確的 MakeSound 方法。

多型範例

1
2
3
4
5
Animal myAnimal1 = new Dog();
Animal myAnimal2 = new Cat();

myAnimal1.MakeSound(); // 輸出:The dog barks.
myAnimal2.MakeSound(); // 輸出:The cat meows.

此例中,myAnimal1myAnimal2 雖然宣告為 Animal 類型,但它們實際上是 DogCat 物件。因此,會根據實際的物件類型呼叫相應的 MakeSound 方法。


4. 抽象類別(Abstract Class)與抽象方法

抽象類別是一種不能被直接實例化的類別,必須通過子類別實現。抽象類別可以包含具體方法和抽象方法。抽象方法只定義簽名,沒有實作,必須由子類別覆寫。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class Animal
{
    public abstract void MakeSound();  // 抽象方法
    public void Eat()
    {
        Console.WriteLine("This animal is eating.");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("The dog barks.");
    }
}

在此範例中,MakeSound 是抽象方法,由 Dog 類別實現。這樣可以確保所有繼承 Animal 的類別都會定義 MakeSound 方法。


實作練習

  1. 創建父類別與子類別
    • Program.cs 中加入以下程式碼:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      
      using System;
      
      class Program
      {
          static void Main(string[] args)
          {
              Animal myDog = new Dog("Buddy");
              myDog.MakeSound();
              myDog.Eat();
      
              Animal myCat = new Cat("Kitty");
              myCat.MakeSound();
          }
      }
      
      public abstract class Animal
      {
          public string Name;
      
          public Animal(string name)
          {
              Name = name;
          }
      
          public void Eat()
          {
              Console.WriteLine(Name + " is eating.");
          }
      
          public abstract void MakeSound();
      }
      
      public class Dog : Animal
      {
          public Dog(string name) : base(name)
          {
          }
      
          public override void MakeSound()
          {
              Console.WriteLine(Name + " barks.");
          }
      }
      
      public class Cat : Animal
      {
          public Cat(string name) : base(name)
          {
          }
      
          public override void MakeSound()
          {
              Console.WriteLine(Name + " meows.");
          }
      }
      
  2. 執行程式
    • 使用指令執行程式:
      1
      
      dotnet run
      
    • 檢視輸出,確認 DogCat 類別的 MakeSound 方法是否正確執行。

教學重點

  • 瞭解繼承在程式中的應用。
  • 使用 base 關鍵字來呼叫父類別的建構函數或方法。
  • 透過 virtualoverride 實現多型。
  • 使用抽象類別和抽象方法,強制子類別實現必要的方法。

在下一節中,我們將學習如何使用介面(Interface)來實現更靈活的設計方式。

本文章以 CC BY 4.0 授權