Python入门(6):面向对象编程(OOP)
目录
1. 面向对象基础概念
1.1 什么是面向对象编程?
2. 类和对象
2.1 类的定义与实例化
2.2 self关键字
3. 面向对象三大特性
3.1 封装(Encapsulation)
3.2 继承(Inheritance)
3.3 多态(Polymorphism)
4. 高级面向对象特性
4.1 类方法和静态方法:咖啡店的故事 ☕
类方法:店长专用工具
4.2 属性装饰器:智能保险箱 🔒
传统方式 vs 属性装饰器
4.3 魔术方法
示例:让书本对象支持加法(合并页数)
常用魔术方法分类
5. 设计模式与最佳实践
5.1 组合优于继承
5.2 SOLID原则
6. Python特有的OOP特性
6.1 多重继承
6.2 Mixin模式
1. 面向对象基础概念
1.1 什么是面向对象编程?
面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它将数据和操作数据的方法组织为对象(Object)。Python是完全支持OOP的语言,其核心概念包括:
-  
类(Class):对象的蓝图或模板
 -  
对象(Object):类的具体实例
 -  
属性(Attribute):对象包含的数据
 -  
方法(Method):对象能执行的操作
 
# 定义一个简单的类
class Dog:
    """狗类的简单示例"""
    
    def __init__(self, name):
        """初始化方法"""
        self.name = name  # 实例属性
        
    def bark(self):
        """实例方法"""
        print(f"{self.name}在汪汪叫!")
# 创建对象
my_dog = Dog("旺财")
my_dog.bark()  # 输出: 旺财在汪汪叫! 
2. 类和对象
2.1 类的定义与实例化
class Person:
    """人类示例"""
    
    # 类属性 (所有实例共享)
    species = "Homo sapiens"
    
    def __init__(self, name, age):
        """构造方法,创建实例时自动调用"""
        self.name = name  # 实例属性
        self.age = age
        
    def introduce(self):
        """实例方法"""
        print(f"我叫{self.name},今年{self.age}岁。")
# 实例化对象
p1 = Person("张三", 25)
p1.introduce()  # 输出: 我叫张三,今年25岁。
print(p1.species)  # 输出: Homo sapiens 
2.2 self关键字
        在类的方法中,self参数代表类的当前实例。Python会自动传递这个参数,你只需要在方法定义时声明它。
class Example:
    def method(self, arg):
        print(f"self: {self}, arg: {arg}")
e = Example()
e.method("test")  # self会自动传入 
3. 面向对象三大特性
3.1 封装(Encapsulation)
封装是将数据和方法包装在类中,并控制外部访问的机制。
class BankAccount:
    """银行账户类,展示封装概念"""
    
    def __init__(self, owner, balance=0):
        """私有属性用单下划线开头(约定,非强制)"""
        self._owner = owner
        self._balance = balance
        
    def deposit(self, amount):
        """存款方法"""
        if amount > 0:
            self._balance += amount
            print(f"存入{amount}元,当前余额: {self._balance}")
        else:
            print("存款金额必须大于0")
    
    def withdraw(self, amount):
        """取款方法"""
        if 0 < amount <= self._balance:
            self._balance -= amount
            print(f"取出{amount}元,当前余额: {self._balance}")
        else:
            print("取款金额无效")
    
    def get_balance(self):
        """获取余额(封装内部实现)"""
        return self._balance
# 使用示例
account = BankAccount("李四", 1000)
account.deposit(500)  # 存入500元,当前余额: 1500
account.withdraw(200)  # 取出200元,当前余额: 1300
print(account.get_balance())  # 1300 
3.2 继承(Inheritance)
继承允许我们定义一个新类来继承现有类的属性和方法。
class Animal:
    """动物基类"""
    
    def __init__(self, name):
        self.name = name
        
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")
        # 如果子类不重写此方法,那么由子类创建的实例在调用这个方法时就会抛出上述异常
class Dog(Animal):
    """Dog类继承Animal"""
    
    def speak(self):
        return f"{self.name}说: 汪汪!"
class Cat(Animal):
    """Cat类继承Animal"""
    
    def speak(self):
        return f"{self.name}说: 喵喵!"
# 使用继承
dog = Dog("阿黄")
cat = Cat("小花")
print(dog.speak())  # 阿黄说: 汪汪!
print(cat.speak())  # 小花说: 喵喵! 
如果对异常不太熟悉,请看这篇文章:Python入门(5):异常处理-CSDN博客
3.3 多态(Polymorphism)
多态指不同类的对象对同一消息做出不同响应。
# 创建一个函数
def animal_sound(animal):
    """多态示例函数"""
    print(animal.speak())
# 传入不同子类对象(即传入不同的实例)
animal_sound(Dog("大黄"))  # 大黄说: 汪汪!
animal_sound(Cat("咪咪"))  # 咪咪说: 喵喵! 
4. 高级面向对象特性
4.1 类方法和静态方法:咖啡店的故事 ☕
类方法:店长专用工具
想象你开了一家咖啡连锁店:
-  
类方法就像店长权限:可以修改所有分店的配方
 -  
自动获取店铺信息:知道当前是哪家分店在调用
 
class CoffeeShop:
    franchise_recipe = "标准配方"  # 所有分店共用
    
    @classmethod
    def change_recipe(cls, new_recipe):
        """修改所有分店的配方"""
        cls.franchise_recipe = new_recipe  # cls自动指向当前类
# 总店修改配方
CoffeeShop.change_recipe("升级配方")
print(CoffeeShop.franchise_recipe)  # 输出:升级配方 
静态方法:店员通用工具
-  
与店铺无关的工具:比如计算找零的方法
 -  
不需要知道店铺信息:就像计算器,谁都可以用
 
class CoffeeShop:
    @staticmethod
    def calculate_change(price, money):
        """计算找零(与店铺状态无关)"""
        return money - price if money >= price else 0
# 任何地方都能用
change = CoffeeShop.calculate_change(30, 50)
print(change)  # 输出:20 
4.2 属性装饰器:智能保险箱 🔒
传统方式 vs 属性装饰器
假设你有一个存钱罐:
# 传统方式(直接访问危险)
class PiggyBank:
    def __init__(self):
        self.money = 0
bank = PiggyBank()
bank.money = -100  # 不合理!但可以随便改 
# 使用属性装饰器(安全访问)
class SafePiggyBank:
    def __init__(self):
        self._money = 0  # 内部变量用下划线
    
    @property
    def money(self):
        """查看余额"""
        return self._money
    
    @money.setter
    def money(self, value):
        """存钱时的安全检查"""
        if value < 0:
            print("金额不能为负!")
            return
        self._money = value
bank = SafePiggyBank()
bank.money = 50   # 正常
bank.money = -30  # 打印警告,值不变
print(bank.money) # 输出:50 
4.3 魔术方法
魔术方法(双下划线方法)允许类自定义特定操作的行为,让自定义对象支持Python的各种语法:
示例:让书本对象支持加法(合并页数)
class Book:
    def __init__(self, title, pages):
        self.title = title
        self.pages = pages
    
    # + 运算符重载
    def __add__(self, other):
        return Book(
            f"{self.title}+{other.title}", 
            self.pages + other.pages
        )
    
    # 打印对象时显示友好信息
    def __str__(self):
        return f"《{self.title}》({self.pages}页)"
# 使用示例
book1 = Book("Python基础", 200)
book2 = Book("算法进阶", 300)
combined = book1 + book2
print(combined)  # 输出:《Python基础+算法进阶》(500页) 
常用魔术方法分类
| 类别 | 方法 | 描述 | 
|---|---|---|
| 对象创建 | __new__ | 实例创建时调用 | 
__init__ | 实例初始化时调用 | |
__del__ | 实例销毁时调用 | |
| 对象表示 | __str__ | 非正式字符串表示 | 
__repr__ | 正式字符串表示 | |
| 运算符重载 | __add__/__sub__ | 加减运算 | 
__eq__/__lt__ | 比较运算 | |
__call__ | 使实例可调用 | |
| 容器行为 | __len__ | 定义容器的长度 | 
__getitem__ | 定义索引访问 | |
| 上下文管理 | __enter__ | with语句进入时调用 | 
__exit__ | with语句退出时调用 | 
小结:什么时候用❓
| 特性 | 使用场景 | 生活比喻 | 
|---|---|---|
| 类方法 | 需要操作类级别数据 | 店长修改所有分店的配方 | 
| 静态方法 | 工具函数,与类/实例无关 | 店铺里的计算器 | 
| 属性装饰器 | 保护数据完整性,添加访问逻辑 | 带密码的保险箱 | 
| 魔术方法 | 让对象支持Python内置操作 | 给普通物品添加超能力 | 
5. 设计模式与最佳实践
5.1 组合优于继承
class Engine:
    """引擎类"""
    def start(self):
        print("引擎启动")
class Wheel:
    """轮胎类"""
    def rotate(self):
        print("轮胎转动")
class Car:
    """使用组合而非继承"""
    def __init__(self):
        self.engine = Engine()
        self.wheels = [Wheel() for _ in range(4)]
    
    def drive(self):
        self.engine.start()
        for wheel in self.wheels:
            wheel.rotate()
        print("汽车行驶中")
# 使用组合
my_car = Car()
my_car.drive() 
5.2 SOLID原则
-  
单一职责原则(SRP):一个类只负责一件事
 -  
开闭原则(OCP):对扩展开放,对修改关闭
 -  
里氏替换原则(LSP):子类应该能替换父类
 -  
接口隔离原则(ISP):客户端不应依赖不需要的接口
 -  
依赖倒置原则(DIP):依赖抽象而非具体实现
# 依赖倒置原则示例 from abc import ABC, abstractmethod class Switchable(ABC): """抽象基类(接口)""" @abstractmethod def turn_on(self): pass @abstractmethod def turn_off(self): pass class LightBulb(Switchable): """具体实现""" def turn_on(self): print("灯泡亮了") def turn_off(self): print("灯泡灭了") class Fan(Switchable): """另一个具体实现""" def turn_on(self): print("风扇转动") def turn_off(self): print("风扇停止") class ElectricPowerSwitch: """依赖抽象而非具体类""" def __init__(self, device: Switchable): self.device = device self.on = False def press(self): if self.on: self.device.turn_off() self.on = False else: self.device.turn_on() self.on = True # 使用示例 light = LightBulb() switch = ElectricPowerSwitch(light) switch.press() # 灯泡亮了 switch.press() # 灯泡灭了 fan = Fan() switch = ElectricPowerSwitch(fan) switch.press() # 风扇转动 switch.press() # 风扇停止 
6. Python特有的OOP特性
6.1 多重继承
class Flyer:
    def fly(self):
        print("飞行中")
class Swimmer:
    def swim(self):
        print("游泳中")
class FlyingFish(Flyer, Swimmer):
    """多重继承"""
    pass
fish = FlyingFish()
fish.fly()  # 飞行中
fish.swim()  # 游泳中 
6.2 Mixin模式
class JsonMixin:
    """Mixin类提供JSON功能"""
    def to_json(self):
        import json
        return json.dumps(self.__dict__)
class XmlMixin:
    """Mixin类提供XML功能"""
    def to_xml(self):
        from xml.etree.ElementTree import Element, tostring
        elem = Element(type(self).__name__)
        for key, value in self.__dict__.items():
            child = Element(key)
            child.text = str(value)
            elem.append(child)
        return tostring(elem)
class Person(JsonMixin, XmlMixin):
    """使用Mixin类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
# 使用Mixin功能
p = Person("王五", 30)
print(p.to_json())  # {"name": "王五", "age": 30}
print(p.to_xml())   # b'<Person><name>王五</name><age>30</age></Person>' 
如果您觉得本文章对您有帮助,别忘了点赞、收藏加关注,更多干货内容将持续发布,您的支持就是作者更新最大的动力。本专栏将持续更新,有任何问题都可以在评论区讨论
