文章

第17天:多型與抽象類別

課程簡介

多型(Polymorphism)和抽象類別是物件導向程式設計(OOP)的兩個核心概念。多型允許不同的類別通過相同的介面來執行不同的操作,使程式更具靈活性和可擴展性。抽象類別是定義了一組子類別必須實現的方法的類別,但不能直接實例化。今天我們將學習如何運用多型和抽象類別來設計靈活且可擴展的程式架構。


學習內容

1. 多型的基本概念

多型允許多個類別共享相同的介面,即使這些類別的具體實現不同。這意味著我們可以使用相同的方法來操作不同類別的物件,而不需要知道它們的具體類型。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog:
    def speak(self):
        return "Bark!"

class Cat:
    def speak(self):
        return "Meow!"

# 函數使用多型
def animal_speak(animal):
    print(animal.speak())

# 創建物件
dog = Dog()
cat = Cat()

animal_speak(dog)  # 輸出: Bark!
animal_speak(cat)  # 輸出: Meow!

在這個範例中,DogCat 類別都實現了 speak() 方法,animal_speak() 函數可以接受這兩種類別的物件並調用相應的方法,而不必關心物件的具體類型。

2. Python 中的多型

Python 中的多型是一種「鴨子類型」(duck typing),這是一個動態語言的特性,只要物件具有某個方法或屬性,它就可以被看作是某個特定的類型,而不必關心這個物件的實際類別。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Bird:
    def fly(self):
        print("Bird is flying.")

class Airplane:
    def fly(self):
        print("Airplane is flying.")

# 使用多型
def fly_thing(thing):
    thing.fly()

bird = Bird()
airplane = Airplane()

fly_thing(bird)     # 輸出: Bird is flying.
fly_thing(airplane) # 輸出: Airplane is flying.

3. 抽象類別的基本概念

抽象類別 是一個定義了方法但無法直接實例化的類別。它用來為子類別提供通用的介面,要求子類別實現具體的方法。Python 使用 abc 模組中的 ABCabstractmethod 來定義抽象類別和抽象方法。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from abc import ABC, abstractmethod

# 定義抽象類別
class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass

# 子類別必須實現抽象方法
class Dog(Animal):
    def speak(self):
        return "Bark!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

dog = Dog()
print(dog.speak())  # 輸出: Bark!

# 無法直接實例化抽象類別
# animal = Animal()  # 這會導致錯誤

在這個範例中,Animal 是一個抽象類別,定義了一個抽象方法 speak(),所有繼承 Animal 的子類別必須實現這個方法。抽象類別無法被直接實例化,只能作為基礎類別提供統一的介面。

4. 抽象類別與多型的結合

抽象類別通常與多型結合使用。通過定義抽象類別,可以確保不同的子類別都實現了相同的介面,從而實現多型操作。

範例:

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
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

# 多型函數
def print_area(shape):
    print(f"The area is: {shape.area()}")

circle = Circle(5)
rectangle = Rectangle(4, 6)

print_area(circle)     # 輸出: The area is: 78.5
print_area(rectangle)  # 輸出: The area is: 24

這裡,Shape 是抽象類別,CircleRectangle 是其子類別。通過 print_area() 函數,我們可以使用多型來計算不同形狀的面積,而不必關心形狀的具體類型。

5. Python 中的介面(Interface)

在某些程式語言中,有一個專門的「介面」類型,用於定義類別必須實現的方法。在 Python 中,我們通常通過抽象類別來模擬介面的功能。抽象類別中的所有方法都是抽象的,子類別必須實現它們。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
from abc import ABC, abstractmethod

class Flyable(ABC):
    @abstractmethod
    def fly(self):
        pass

class Bird(Flyable):
    def fly(self):
        print("Bird is flying.")

bird = Bird()
bird.fly()  # 輸出: Bird is flying.

教學重點

  • 多型的概念:理解如何通過相同的介面實現不同類別的操作。
  • 抽象類別:學會如何使用抽象類別來強制子類別實現特定方法。
  • abc 模組:學習如何使用 abc 模組來定義抽象類別和抽象方法。
  • 多型與抽象類別的結合:掌握如何通過抽象類別來實現多型,從而設計更靈活的程式架構。

任務

  1. 創建一個抽象類別 Vehicle,定義一個抽象方法 drive(),然後創建兩個子類別 CarBike,並實現各自的 drive() 方法。
  2. 創建一個抽象類別 Shape,定義一個抽象方法 perimeter(),然後創建兩個子類別 SquareTriangle,並實現計算周長的功能。
  3. 使用多型創建一個函數 describe_animal(animal),接受一個 Animal 類別或其子類別的物件,並呼叫 speak() 方法來輸出聲音。
  4. 創建一個抽象類別 Appliance,並定義抽象方法 turn_on()turn_off(),然後創建兩個子類別 FanLight,實現各自的開關功能。
本文章以 CC BY 4.0 授權