Python 繼承 (Inheritance)
繼承讓子類別可以繼承父類別的屬性和方法,實現程式碼重用和擴展。
基本繼承
# 父類別(基類別)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
# 子類別(衍生類別)
class Dog(Animal):
def bark(self):
print(f"{self.name} says: Woof!")
# 使用
dog = Dog("Buddy")
dog.speak() # Buddy makes a sound(繼承自 Animal)
dog.bark() # Buddy says: Woof!(Dog 自己的方法)
方法覆寫 (Override)
子類別可以覆寫父類別的方法:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
class Dog(Animal):
def speak(self):
print(f"{self.name} says: Woof!")
class Cat(Animal):
def speak(self):
print(f"{self.name} says: Meow!")
dog = Dog("Buddy")
cat = Cat("Whiskers")
dog.speak() # Buddy says: Woof!
cat.speak() # Whiskers says: Meow!
super() 函數
使用 super() 呼叫父類別的方法:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
return f"{self.name}, {self.age} years old"
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age) # 呼叫父類別的 __init__
self.breed = breed
def info(self):
base_info = super().info() # 呼叫父類別的 info
return f"{base_info}, breed: {self.breed}"
dog = Dog("Buddy", 3, "Labrador")
print(dog.info()) # Buddy, 3 years old, breed: Labrador
isinstance() 和 issubclass()
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# isinstance 檢查物件是否為某類別的實例
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True(Dog 繼承自 Animal)
print(isinstance(dog, object)) # True(所有類別都繼承自 object)
# issubclass 檢查類別是否為另一類別的子類別
print(issubclass(Dog, Animal)) # True
print(issubclass(Dog, object)) # True
print(issubclass(Animal, Dog)) # False
多重繼承
Python 支援多重繼承,一個類別可以繼承多個父類別:
class Flyable:
def fly(self):
print("Flying...")
class Swimmable:
def swim(self):
print("Swimming...")
class Duck(Flyable, Swimmable):
def quack(self):
print("Quack!")
duck = Duck()
duck.fly() # Flying...
duck.swim() # Swimming...
duck.quack() # Quack!
方法解析順序 (MRO)
當多個父類別有相同的方法時,Python 使用 MRO 來決定呼叫哪一個:
class A:
def method(self):
print("A")
class B(A):
def method(self):
print("B")
class C(A):
def method(self):
print("C")
class D(B, C):
pass
d = D()
d.method() # B(根據 MRO)
# 查看 MRO
print(D.__mro__)
# (<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)
使用 super() 處理多重繼承
class A:
def __init__(self):
print("A init")
super().__init__()
class B(A):
def __init__(self):
print("B init")
super().__init__()
class C(A):
def __init__(self):
print("C init")
super().__init__()
class D(B, C):
def __init__(self):
print("D init")
super().__init__()
d = D()
輸出:
D init
B init
C init
A init
Mixin
Mixin 是一種提供額外功能的類別,通常不獨立使用:
class JsonMixin:
def to_json(self):
import json
return json.dumps(self.__dict__)
class LogMixin:
def log(self, message):
print(f"[{self.__class__.__name__}] {message}")
class User(JsonMixin, LogMixin):
def __init__(self, name, email):
self.name = name
self.email = email
user = User("Alice", "alice@example.com")
print(user.to_json()) # {"name": "Alice", "email": "alice@example.com"}
user.log("User created") # [User] User created
抽象類別
使用 abc 模組建立抽象類別,強制子類別實作特定方法:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
# shape = Shape() # TypeError: 不能實例化抽象類別
rect = Rectangle(5, 3)
print(rect.area()) # 15
print(rect.perimeter()) # 16
實際範例
from abc import ABC, abstractmethod
class Employee(ABC):
def __init__(self, name, salary):
self.name = name
self.salary = salary
@abstractmethod
def calculate_bonus(self):
pass
def __str__(self):
return f"{self.name} - ${self.salary}"
class Manager(Employee):
def __init__(self, name, salary, team_size):
super().__init__(name, salary)
self.team_size = team_size
def calculate_bonus(self):
return self.salary * 0.2 + self.team_size * 100
class Developer(Employee):
def __init__(self, name, salary, programming_languages):
super().__init__(name, salary)
self.programming_languages = programming_languages
def calculate_bonus(self):
return self.salary * 0.1 + len(self.programming_languages) * 50
# 使用
manager = Manager("Alice", 80000, 5)
developer = Developer("Bob", 70000, ["Python", "JavaScript", "Go"])
print(f"{manager.name}'s bonus: ${manager.calculate_bonus()}")
# Alice's bonus: $16500.0
print(f"{developer.name}'s bonus: ${developer.calculate_bonus()}")
# Bob's bonus: $7150.0