面向对象编程(OOP)是Python的核心编程范式之一,它使用"对象"的概念来组织代码和数据。

四大基本特性

1. 封装 (Encapsulation)

将数据和行为包装在一个单元(类)中,并控制对内部实现的访问。

2. 继承 (Inheritance)

允许创建新类基于现有类,重用父类的属性和方法。

3. 多态 (Polymorphism)

同一操作作用于不同的对象,可以有不同的解释和执行结果。

4. 抽象 (Abstraction)

隐藏复杂的实现细节,只暴露必要的接口。

类与对象

基本类定义

class Dog:
    # 类属性(所有实例共享)
    species = "Canis familiaris"
    
    # 初始化方法(构造函数)
    def __init__(self, name, age):
        # 实例属性
        self.name = name
        self.age = age
    
    # 实例方法
    def bark(self):
        return f"{self.name} says: Woof!"
    
    def get_info(self):
        return f"{self.name} is {self.age} years old"

创建和使用对象

# 创建对象实例
my_dog = Dog("Buddy", 3)
your_dog = Dog("Lucy", 5)

print(my_dog.bark())  # Buddy says: Woof!
print(your_dog.get_info())  # Lucy is 5 years old
print(Dog.species)  # Canis familiaris (访问类属性)

继承

单继承

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

class Cat(Animal):  # 继承Animal类
    def __init__(self, name, color):
        super().__init__(name)  # 调用父类初始化方法
        self.color = color
    
    def speak(self):  # 重写父类方法
        return "Meow!"
    
    def purr(self):   # 子类特有方法
        return "Purrrr..."

# 使用
my_cat = Cat("Whiskers", "orange")
print(my_cat.speak())  # Meow!
print(my_cat.purr())   # Purrrr...

多继承

class Flyable:
    def fly(self):
        return "I can fly!"

class Swimmable:
    def swim(self):
        return "I can swim!"

class Duck(Flyable, Swimmable):
    def __init__(self, name):
        self.name = name
    
    def quack(self):
        return "Quack!"

# 使用
duck = Duck("Donald")
print(duck.fly())   # I can fly!
print(duck.swim())  # I can swim!
print(duck.quack()) # Quack!

封装与访问控制

Python使用命名约定来实现访问控制:

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner       # 公共属性
        self._account_number = "123456"  # 受保护属性(约定)
        self.__balance = balance  # 私有属性(名称修饰)
    
    # 公共方法
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return True
        return False
    
    def get_balance(self):
        return self.__balance
    
    # 私有方法
    def __update_records(self):
        print("更新记录...")

# 使用
account = BankAccount("Alice", 1000)
print(account.owner)          # Alice (可访问)
print(account._account_number) # 123456 (可访问但不推荐)
# print(account.__balance)     # 错误!AttributeError
print(account.get_balance())  # 1000 (通过方法访问)

多态

class Shape:
    def area(self):
        pass

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

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

# 多态演示
def print_area(shape):
    print(f"面积: {shape.area()}")

rect = Rectangle(5, 3)
circle = Circle(4)

print_area(rect)   # 面积: 15
print_area(circle) # 面积: 50.24

特殊方法(魔术方法)

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    # 字符串表示
    def __str__(self):
        return f"Vector({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"
    
    # 算术运算
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)
    
    # 比较运算
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    # 长度
    def __len__(self):
        return int((self.x**2 + self.y**2)**0.5)

# 使用
v1 = Vector(2, 3)
v2 = Vector(1, 2)

print(v1 + v2)  # Vector(3, 5)
print(v1 - v2)  # Vector(1, 1)
print(v1 == v2) # False
print(len(v1))  # 3

属性装饰器

class Person:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
    
    @property
    def full_name(self):
        return f"{self.first_name} {self.last_name}"
    
    @full_name.setter
    def full_name(self, name):
        first, last = name.split(" ")
        self.first_name = first
        self.last_name = last
    
    @property
    def email(self):
        return f"{self.first_name.lower()}.{self.last_name.lower()}@email.com"

# 使用
person = Person("John", "Doe")
print(person.full_name)  # John Doe
print(person.email)      # john.doe@email.com

person.full_name = "Jane Smith"
print(person.first_name) # Jane
print(person.last_name)  # Smith

类方法和静态方法

class MyClass:
    class_attribute = "类属性"
    
    def __init__(self, value):
        self.instance_attribute = value
    
    @classmethod
    def class_method(cls):
        print(f"这是类方法,可以访问类属性: {cls.class_attribute}")
        # 不能访问实例属性
    
    @staticmethod
    def static_method():
        print("这是静态方法,不能访问类或实例属性")
    
    def instance_method(self):
        print(f"这是实例方法,可以访问实例属性: {self.instance_attribute}")

# 使用
MyClass.class_method()   # 通过类调用
MyClass.static_method()  # 通过类调用

obj = MyClass("实例值")
obj.instance_method()    # 通过实例调用

抽象基类

from abc import ABC, abstractmethod

class Vehicle(ABC):
    @abstractmethod
    def start_engine(self):
        pass
    
    @abstractmethod
    def stop_engine(self):
        pass

class Car(Vehicle):
    def start_engine(self):
        return "汽车引擎启动"
    
    def stop_engine(self):
        return "汽车引擎停止"

class Motorcycle(Vehicle):
    def start_engine(self):
        return "摩托车引擎启动"
    
    def stop_engine(self):
        return "摩托车引擎停止"

# 不能直接实例化抽象类
# vehicle = Vehicle()  # 错误!

car = Car()
print(car.start_engine())  # 汽车引擎启动

实际应用示例

示例:简单的电商系统

class Product:
    def __init__(self, name, price, quantity):
        self.name = name
        self.price = price
        self.quantity = quantity
    
    def get_total_value(self):
        return self.price * self.quantity

class ShoppingCart:
    def __init__(self):
        self.items = []
    
    def add_item(self, product, quantity=1):
        self.items.append((product, quantity))
    
    def remove_item(self, product_name):
        self.items = [item for item in self.items if item[0].name != product_name]
    
    def get_total(self):
        return sum(product.price * quantity for product, quantity in self.items)
    
    def __str__(self):
        if not self.items:
            return "购物车为空"
        
        result = "购物车内容:\n"
        for product, quantity in self.items:
            result += f"- {product.name}: ${product.price} x {quantity} = ${product.price * quantity}\n"
        result += f"总计: ${self.get_total()}"
        return result

# 使用
product1 = Product("笔记本电脑", 1000, 2)
product2 = Product("鼠标", 25, 5)

cart = ShoppingCart()
cart.add_item(product1, 1)
cart.add_item(product2, 2)

print(cart)

最佳实践

  1. 遵循单一职责原则:一个类只负责一个功能领域
  2. 使用组合优于继承:优先使用对象组合而不是类继承
  3. 保持类小而专注:避免创建过于庞大的类
  4. 使用属性访问控制:适当使用私有和受保护属性
  5. 提供清晰的接口:方法命名应该清晰表达其功能

总结

Python的面向对象编程提供了强大的工具来创建模块化、可重用和可维护的代码。通过合理使用类、对象、继承、多态和封装,你可以构建复杂的应用程序同时保持代码的清晰和可扩展性。

掌握OOP概念是成为高级Python开发者的关键步骤,它帮助你以更结构化和组织化的方式思考问题解决方案。