Python 的面向對象編程(OOP)通過類(Class)和對象(Object)實現代碼結構化,支持封裝、繼承和多態三大特性。以下是系統化指南:
一、類與對象基礎
1. 定義類
class Dog:# 類屬性(所有實例共享)species = "Canis familiaris"# 構造方法(__init__是魔法方法)def __init__(self, name, age):self.name = name # 實例屬性self.age = age# 實例方法def bark(self):return f"{self.name} says: Woof!"# 創建對象
my_dog = Dog("Buddy", 3)
print(my_dog.species) # 輸出: Canis familiaris
2. 特殊方法(Magic Methods)
class Rectangle:def __init__(self, width, height):self.width = widthself.height = height# 計算面積def area(self):return self.width * self.height# 字符串表示(__str__用于用戶友好顯示)def __str__(self):return f"Rectangle({self.width}x{self.height})"# 運算符重載(實現加法)def __add__(self, other):return Rectangle(self.width + other.width,self.height + other.height)rect1 = Rectangle(2, 3)
rect2 = Rectangle(4, 5)
print(rect1 + rect2) # 輸出: Rectangle(6x8)
二、繼承與方法重寫
1. 單繼承
class Animal:def __init__(self, name):self.name = namedef speak(self):raise NotImplementedError("子類必須實現此方法")class Dog(Animal):def speak(self):return f"{self.name} says: Woof!"class Cat(Animal):def speak(self):return f"{self.name} says: Meow!"animals = [Dog("Buddy"), Cat("Whiskers")]
for animal in animals:print(animal.speak())
2. 多重繼承
class Flyer:def fly(self):return "Flying!"class Swimmer:def swim(self):return "Swimming!"class Duck(Flyer, Swimmer):def __init__(self, name):self.name = nameduck = Duck("Donald")
print(duck.fly()) # 輸出: Flying!
print(duck.swim()) # 輸出: Swimming!
3. super() 函數
class Rectangle:def __init__(self, width, height):self.width = widthself.height = heightclass ColoredRectangle(Rectangle):def __init__(self, width, height, color):super().__init__(width, height) # 調用父類構造方法self.color = color
三、多態與鴨子類型
1. 運行時多態
class Shape:def area(self):passclass Circle(Shape):def __init__(self, radius):self.radius = radiusdef area(self):return 3.14 * self.radius ** 2class Square(Shape):def __init__(self, side):self.side = sidedef area(self):return self.side ** 2def print_area(shape):print(shape.area())print_area(Circle(5)) # 輸出: 78.5
print_area(Square(4)) # 輸出: 16
2. 鴨子類型(Duck Typing)
class Duck:def quack(self):print("Quack!")class FakeDuck:def quack(self):print("Silent quack")def make_quack(duck):duck.quack()make_quack(Duck()) # 輸出: Quack!
make_quack(FakeDuck()) # 輸出: Silent quack
四、封裝與訪問控制
1. 屬性控制
class BankAccount:def __init__(self, balance=0):self.__balance = balance # 雙下劃線前綴實現名稱修飾@propertydef balance(self):return self.__balance@balance.setterdef balance(self, value):if value < 0:raise ValueError("余額不能為負")self.__balance = valueaccount = BankAccount(100)
account.balance = 200 # 允許修改
# account.balance = -50 # 拋出 ValueError
2. 描述符協議
class NonNegative:def __set_name__(self, owner, name):self.name = namedef __get__(self, instance, owner):return instance.__dict__[self.name]def __set__(self, instance, value):if value < 0:raise ValueError("值不能為負")instance.__dict__[self.name] = valueclass Product:price = NonNegative()stock = NonNegative()def __init__(self, price, stock):self.price = priceself.stock = stockproduct = Product(19.99, 100)
# product.price = -5 # 拋出 ValueError
五、高級特性
1. 元類(Metaclass)
class Singleton(type):_instances = {}def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super().__call__(*args, **kwargs)return cls._instances[cls]class Database(metaclass=Singleton):passdb1 = Database()
db2 = Database()
print(db1 is db2) # 輸出: True
2. 抽象基類(ABC)
from abc import ABC, abstractmethodclass PaymentGateway(ABC):@abstractmethoddef process_payment(self, amount):passclass PayPal(PaymentGateway):def process_payment(self, amount):print(f"PayPal 處理支付: ${amount}")# class FakeGateway(PaymentGateway): pass # 實例化會報錯
六、設計模式應用
1. 工廠模式
class ShapeFactory:@staticmethoddef create_shape(shape_type, **kwargs):shapes = {'circle': Circle,'square': Square}return shapes[shape_type](**kwargs)circle = ShapeFactory.create_shape('circle', radius=5)
2. 單例模式
class Database:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls)cls._instance._initialized = Falsereturn cls._instancedef __init__(self):if not self._initialized:self.connect()self._initialized = Truedef connect(self):print("建立數據庫連接")
七、最佳實踐
- 組合優于繼承:優先使用對象組合而非類繼承
- 顯式優于隱式:避免過度依賴魔術方法
- 保持簡單:單個類職責不超過7個方法(參考SRP原則)
- 文檔字符串:為每個類和方法編寫docstring
- 類型注解(Python 3.5+):
class Vector:def __init__(self, x: float, y: float):self.x = xself.y = y
掌握這些面向對象技術后,可進一步探索設計模式(如MVC、觀察者模式)和框架開發(如Django的類視圖)。建議通過實際項目(如開發電商系統、游戲引擎)深化理解。