【python】OOP:Object-Oriented Programming

文章目录

    • [1. 面向对象编程的核心概念](#1. 面向对象编程的核心概念)
      • [1.1 类与对象的关系](#1.1 类与对象的关系)
      • [1.2 封装(Encapsulation)](#1.2 封装(Encapsulation))
    • [2. 继承与多态](#2. 继承与多态)
      • [2.1 继承机制](#2.1 继承机制)
      • [2.2 多重继承](#2.2 多重继承)
      • [2.3 多态性](#2.3 多态性)
    • [3. 特殊方法与运算符重载](#3. 特殊方法与运算符重载)
    • [4. 抽象类与接口](#4. 抽象类与接口)
      • [4.1 抽象基类](#4.1 抽象基类)
    • [5. 组合与聚合](#5. 组合与聚合)
    • [6. 属性管理](#6. 属性管理)
      • [6.1 使用property装饰器](#6.1 使用property装饰器)
      • [6.2 描述符协议](#6.2 描述符协议)
    • [7. 元类与类装饰器](#7. 元类与类装饰器)
      • [7.1 元类](#7.1 元类)
      • [7.2 类装饰器](#7.2 类装饰器)
    • [8. 设计模式实践](#8. 设计模式实践)
      • [8.1 观察者模式](#8.1 观察者模式)

1. 面向对象编程的核心概念

面向对象编程(OOP)是一种编程范式,它将数据和操作数据的方法封装在一起,形成对象。Python作为一门多范式编程语言,对OOP提供了强大的支持。

1.1 类与对象的关系

类是对象的模板或蓝图,定义了对象的属性和行为。对象是类的实例,是具体的数据实体。这种关系类似于建筑图纸与实际建筑物的关系。

python 复制代码
class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model
    
    def start(self):
        return f"{self.brand} {self.model} is starting"

# 创建对象实例
my_car = Car("Toyota", "Camry")
print(my_car.start())  # Toyota Camry is starting

1.2 封装(Encapsulation)

封装是将数据和方法绑定在一起,并限制对对象内部状态的直接访问。Python通过命名约定来实现封装:

  • 公共属性:直接访问
  • 受保护属性:以单下划线开头(_attribute)
  • 私有属性:以双下划线开头(__attribute)
python 复制代码
class BankAccount:
    def __init__(self, balance):
        self._balance = balance  # 受保护属性
        self.__account_number = "123456789"  # 私有属性
    
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
    
    def get_balance(self):
        return self._balance
    
    def _internal_method(self):  # 受保护方法
        return "Internal processing"

2. 继承与多态

2.1 继承机制

继承允许一个类获得另一个类的属性和方法,促进代码重用并建立类之间的层次关系。

python 复制代码
class Vehicle:
    def __init__(self, brand, year):
        self.brand = brand
        self.year = year
    
    def start(self):
        return "Vehicle is starting"
    
    def stop(self):
        return "Vehicle is stopping"

class ElectricCar(Vehicle):
    def __init__(self, brand, year, battery_capacity):
        super().__init__(brand, year)  # 调用父类构造函数
        self.battery_capacity = battery_capacity
    
    def charge(self):
        return f"Charging {self.brand} with {self.battery_capacity}kWh battery"
    
    def start(self):  # 方法重写
        return f"Electric {self.brand} is silently starting"

2.2 多重继承

Python支持多重继承,但需要注意方法解析顺序(MRO)。

python 复制代码
class Flyable:
    def fly(self):
        return "Flying in the sky"

class Swimmable:
    def swim(self):
        return "Swimming in water"

class Duck(Flyable, Swimmable):
    def __init__(self, name):
        self.name = name
    
    def quack(self):
        return f"{self.name} says quack!"

# 查看方法解析顺序
print(Duck.__mro__)

2.3 多态性

多态性允许不同类的对象对同一消息做出不同的响应,通过统一的接口处理不同类型的对象。

python 复制代码
class Shape:
    def area(self):
        raise NotImplementedError("Subclass must implement area method")

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.14159 * self.radius ** 2

# 多态性的体现
def print_area(shape):
    print(f"Area: {shape.area()}")

shapes = [Rectangle(5, 3), Circle(4)]
for shape in shapes:
    print_area(shape)  # 同一接口,不同实现

3. 特殊方法与运算符重载

Python提供了丰富的特殊方法(魔术方法),允许类定义对象的行为。

python 复制代码
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!r}, {self.y!r})"
    
    def __add__(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(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)  # Vector(4, 6)
print(v1 == v2)  # False

4. 抽象类与接口

4.1 抽象基类

使用abc模块创建抽象基类,强制子类实现特定方法。

python 复制代码
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        pass
    
    @abstractmethod
    def move(self):
        pass
    
    def sleep(self):  # 具体方法
        return "Animal is sleeping"

class Dog(Animal):
    def make_sound(self):
        return "Woof!"
    
    def move(self):
        return "Dog is running"

# Animal()  # 会报错,不能实例化抽象类
dog = Dog()
print(dog.make_sound())  # Woof!

5. 组合与聚合

组合是一种"has-a"关系,表示整体与部分的强关联。

python 复制代码
class Engine:
    def __init__(self, horsepower):
        self.horsepower = horsepower
    
    def start(self):
        return f"Engine with {self.horsepower}HP is starting"

class Car:
    def __init__(self, brand, engine):
        self.brand = brand
        self.engine = engine  # 组合关系
    
    def start(self):
        return f"{self.brand}: {self.engine.start()}"

engine = Engine(200)
car = Car("BMW", engine)
print(car.start())  # BMW: Engine with 200HP is starting

6. 属性管理

6.1 使用property装饰器

python 复制代码
class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius
    
    @property
    def celsius(self):
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Temperature below absolute zero is not possible")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        return (self._celsius * 9/5) + 32
    
    @fahrenheit.setter
    def fahrenheit(self, value):
        self.celsius = (value - 32) * 5/9

temp = Temperature(25)
print(temp.fahrenheit)  # 77.0
temp.fahrenheit = 86
print(temp.celsius)     # 30.0

6.2 描述符协议

描述符提供了更高级的属性控制机制。

python 复制代码
class Validator:
    def __init__(self, min_value=0, max_value=100):
        self.min_value = min_value
        self.max_value = max_value
    
    def __set_name__(self, owner, name):
        self.name = name
    
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__[self.name]
    
    def __set__(self, instance, value):
        if not (self.min_value <= value <= self.max_value):
            raise ValueError(f"{self.name} must be between {self.min_value} and {self.max_value}")
        instance.__dict__[self.name] = value

class Student:
    grade = Validator(0, 100)
    
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade  # 使用描述符验证

7. 元类与类装饰器

7.1 元类

元类是创建类的类,控制类的创建过程。

python 复制代码
class SingletonMeta(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=SingletonMeta):
    def __init__(self):
        self.connection = "Connected to database"

db1 = Database()
db2 = Database()
print(db1 is db2)  # True,单例模式

7.2 类装饰器

类装饰器提供了修改类行为的简洁方式。

python 复制代码
def add_logging(cls):
    original_init = cls.__init__
    
    def new_init(self, *args, **kwargs):
        print(f"Creating instance of {cls.__name__}")
        original_init(self, *args, **kwargs)
    
    cls.__init__ = new_init
    return cls

@add_logging
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

product = Product("Laptop", 999)  # 输出: Creating instance of Product

8. 设计模式实践

8.1 观察者模式

python 复制代码
class Subject:
    def __init__(self):
        self._observers = []
        self._state = None
    
    def attach(self, observer):
        self._observers.append(observer)
    
    def detach(self, observer):
        self._observers.remove(observer)
    
    def notify(self):
        for observer in self._observers:
            observer.update(self._state)
    
    def set_state(self, state):
        self._state = state
        self.notify()

class Observer:
    def update(self, state):
        print(f"Observer received update: {state}")

subject = Subject()
observer1 = Observer()
observer2 = Observer()

subject.attach(observer1)
subject.attach(observer2)
subject.set_state("New State")  # 通知所有观察者