繼承

Python SELF TW
等級 15 , 課堂 6
開放

6.1 繼承 — 很簡單啦

繼承是物件導向程式設計(OOP)的一個基本概念,它允許一個類別(稱為子類別)繼承另一個類別的屬性和方法(稱為父類別或超類別)。

這種方法可以創建比較通用的類別,重複使用代碼,提升代碼的組織性和可維護性。

為啥要用繼承呢?

假設你需要寫點代碼,並決定以類別的形式來做。然後你發現項目中已經有個類別,幾乎做了你需要的一切。你可以直接複製這個類別的代碼,然後用得開心。

或者你可以「像是複製」的樣子。你可以定義那個類別為你類別的父類,然後 Python 會給你的類別添加父類的行為。

想像一下你是大自然,想創造一隻狗。是從細菌開始花十億年創造一隻狗更快,還是馴化狼需要大約二十萬年更快?

基本繼承範例

假設你有一個父類別 Animal,帶有屬性 name:


class Animal:
    def __init__(self, name):
        self.name = name

我們想為它創建兩個子類別 — DogCat,還要給它們都加上方法 speak


class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

在上面的例子中,子類別 DogCat 繼承自 Animal 並添加了 speak 方法。

類別 Dog

  • 繼承了 Animal 的屬性 name
  • 添加了 speak 方法,返回特定於狗的字符串。

類別 Cat

  • 繼承了 Animal 的屬性 name
  • 添加了 speak 方法,返回特定於貓的字符串。

最終代碼如下所示:


class Animal:
    def __init__(self, name):
        self.name = name
         
class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"
        
class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"
         
dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # 會輸出:Buddy says Woof!
print(cat.speak())  # 會輸出:Whiskers says Meow!

在這個例子中,Animal 是父類別,DogCat 是子類別。子類別繼承自父類別 Animal 的屬性 name 和方法 __init__,並添加了 speak 方法。

6.2 繼承的幕後運作

如果你給你的類別添加了父類,這就像是你把父類的代碼複製到你的類別裡一樣。


class Animal:
    def __init__(self, name):
        self.name = name
         

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)  # 呼叫父類別的構造函數
        
    def speak(self):
        return f"{self.name} says Woof!"
        
class Cat(Animal):
    def __init__(self, name):
        super().__init__(name)  # 呼叫父類別的構造函數
        
    def speak(self):
        return f"{self.name} says Meow!"
        

dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # 會輸出:Buddy says Woof!
print(cat.speak())  # 會輸出:Whiskers says Meow!

這個描述並不完全準確,但如果你從來沒有接觸過繼承的概念,可以暫時這樣思考。我們之後會加上更多細節。

6.3 繼承的層次結構

在設計大規模類別群組的複雜模型時,你可能會遇到整個繼承的層次結構。

例如,你有一個類別 Animal — 這是所有動物的基類:


class Animal:
    def __init__(self, name):
        self.name = name
        
    def speak(self):
        raise NotImplementedError("Subclass must implement abstract method")

我們甚至還給它添加了 speak 方法,但是因為抽象的動物不會說話,這個方法只會拋出 NotImplementedError — 這是標準做法。

然後我們添加了中間類別,這些類別對應於動物的分類:Mammal 是哺乳動物,Bird 是鳥類。


class Mammal(Animal):
    def __init__(self, name, fur_color):
        super().__init__(name)  # 呼叫父類別的構造函數
        self.fur_color = fur_color
         

class Bird(Animal):
    def __init__(self, name, wing_span):
        super().__init__(name)  # 呼叫父類別的構造函數
        self.wing_span = wing_span
        
    def fly(self):
        return f"{self.name} is flying with a wingspan of {self.wing_span} meters."

最後一步是創建具體的動物類別:


class Dog(Mammal):
    def speak(self):
        return f"{self.name} says Woof!"
         
        
class Cat(Mammal):
    def speak(self):
        return f"{self.name} says Meow!"
        
class Parrot(Bird):
    def speak(self):
        return f"{self.name} says Squawk!"

通常最終的代碼會和這些類別一起工作:


animals = [Dog("Buddy", "brown"), Cat("Whiskers", "white"), Parrot("Polly", 0.5)]
            
for animal in animals:
    print(animal.speak())

print(f"{dog.name} has {dog.fur_color} fur.")  # 會輸出:Buddy has brown fur.
print(f"{cat.name} has {cat.fur_color} fur.")  # 會輸出:Whiskers has white fur.
print(parrot.fly())  # 會輸出:Polly is flying with a wingspan of 0.5 meters.

雖然從技術上講,創建數十個祖先的繼承層次結構沒有禁止,但是要記住在沒有必要的情況下最好保持簡單。簡單才是真正的力量。

1
Опрос
類別與面向物件程式設計,  15 уровень,  6 лекция
недоступен
類別與面向物件程式設計
類別與面向物件程式設計
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION