Python面向对象编程:从代码搬运工到架构师

面向对象编程(OOP)让你用现实世界的思维来组织代码,把数据和操作封装成对象,让代码更模块化、更易维护

从面条代码到清晰架构

面向过程 vs 面向对象

python 复制代码
# 🚫 面向过程:一堆散乱的函数和数据
def calculate_employee_salary(hours_worked, hourly_rate, tax_rate):
    gross_pay = hours_worked * hourly_rate
    tax_amount = gross_pay * tax_rate
    net_pay = gross_pay - tax_amount
    return net_pay

def print_employee_info(name, department, salary):
    print(f"{name} 在 {department} 部门,月薪 {salary}")

def save_employee_to_db(name, department, salary):
    # 模拟保存到数据库
    print(f"保存 {name} 的信息到数据库")

# 使用这些函数
name = "张三"
department = "技术部"
hours_worked = 160
hourly_rate = 100
tax_rate = 0.2

salary = calculate_employee_salary(hours_worked, hourly_rate, tax_rate)
print_employee_info(name, department, salary)
save_employee_to_db(name, department, salary)

现在看看面向对象的做法:

python 复制代码
# ✅ 面向对象:清晰的封装
class Employee:
    def __init__(self, name, department, hourly_rate):
        self.name = name
        self.department = department
        self.hourly_rate = hourly_rate
        self.tax_rate = 0.2
    
    def calculate_salary(self, hours_worked):
        gross_pay = hours_worked * self.hourly_rate
        tax_amount = gross_pay * self.tax_rate
        return gross_pay - tax_amount
    
    def display_info(self, hours_worked):
        salary = self.calculate_salary(hours_worked)
        print(f"{self.name} 在 {self.department} 部门,月薪 {salary}")
    
    def save_to_database(self):
        print(f"保存 {self.name} 的信息到数据库")

# 使用对象
employee = Employee("张三", "技术部", 100)
employee.display_info(160)
employee.save_to_database()

面向对象三大支柱

1. 封装:信息隐藏的艺术

python 复制代码
class BankAccount:
    def __init__(self, account_holder, initial_balance=0):
        self.account_holder = account_holder
        self._balance = initial_balance  # 受保护的属性
        self.__account_number = self._generate_account_number()  # 私有属性
    
    def _generate_account_number(self):
        """生成账户号码(内部方法)"""
        import random
        return f"ACC{random.randint(100000, 999999)}"
    
    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}")
            return True
        else:
            print("取款失败:余额不足或金额无效")
            return False
    
    def get_balance(self):
        """获取余额(通过方法访问受保护属性)"""
        return self._balance
    
    def get_account_info(self):
        """获取账户信息(公开接口)"""
        return {
            "account_holder": self.account_holder,
            "balance": self._balance,
            "account_number": self.__account_number  # 只能在类内部访问
        }

# 使用封装
account = BankAccount("李四", 1000)
account.deposit(500)           # ✅ 正确的操作方式
# account._balance = 1000000   # ❌ 不应该直接修改内部状态
# print(account.__account_number)  # ❌ 无法访问私有属性

print(f"当前余额: {account.get_balance()}")
print(f"账户信息: {account.get_account_info()}")

2. 继承:代码复用的智慧

python 复制代码
# 基类:通用员工
class Employee:
    def __init__(self, name, employee_id, base_salary):
        self.name = name
        self.employee_id = employee_id
        self.base_salary = base_salary
    
    def calculate_salary(self):
        """计算基本工资"""
        return self.base_salary
    
    def get_info(self):
        """获取员工信息"""
        return f"{self.name} (ID: {self.employee_id})"

# 派生类:经理
class Manager(Employee):
    def __init__(self, name, employee_id, base_salary, bonus):
        super().__init__(name, employee_id, base_salary)  # 调用父类构造器
        self.bonus = bonus
        self.team_size = 0
    
    def calculate_salary(self):
        """重写工资计算方法(经理有奖金)"""
        return self.base_salary + self.bonus
    
    def manage_team(self, team_size):
        """经理特有的方法"""
        self.team_size = team_size
        print(f"{self.name} 正在管理 {team_size} 人的团队")

# 派生类:开发人员
class Developer(Employee):
    def __init__(self, name, employee_id, base_salary, programming_language):
        super().__init__(name, employee_id, base_salary)
        self.programming_language = programming_language
        self.projects = []
    
    def add_project(self, project_name):
        """开发人员特有的方法"""
        self.projects.append(project_name)
        print(f"{self.name} 参与了项目: {project_name}")
    
    def get_info(self):
        """重写获取信息方法"""
        base_info = super().get_info()
        return f"{base_info} - {self.programming_language} 开发工程师"

# 使用继承
manager = Manager("王总监", "M001", 15000, 5000)
developer = Developer("张工程师", "D001", 12000, "Python")

print("=== 员工信息 ===")
print(f"经理: {manager.get_info()}, 月薪: {manager.calculate_salary()}")
print(f"开发: {developer.get_info()}, 月薪: {developer.calculate_salary()}")

manager.manage_team(8)      # 经理特有方法
developer.add_project("电商系统")  # 开发人员特有方法

3. 多态:灵活应对变化

python 复制代码
from math import pi

class Shape:
    """形状基类"""
    def area(self):
        """计算面积(抽象方法)"""
        raise NotImplementedError("子类必须实现此方法")
    
    def perimeter(self):
        """计算周长(抽象方法)"""
        raise NotImplementedError("子类必须实现此方法")

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)

class Circle(Shape):
    """圆形"""
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return pi * self.radius ** 2
    
    def perimeter(self):
        return 2 * pi * self.radius

class Triangle(Shape):
    """三角形"""
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
    
    def area(self):
        # 使用海伦公式
        s = self.perimeter() / 2
        return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5
    
    def perimeter(self):
        return self.a + self.b + self.c

# 多态的威力:统一处理不同对象
def print_shape_info(shape):
    """打印形状信息 - 接受任何Shape对象"""
    print(f"{type(shape).__name__}: 面积={shape.area():.2f}, 周长={shape.perimeter():.2f}")

# 创建不同形状
shapes = [
    Rectangle(10, 5),
    Circle(3),
    Triangle(3, 4, 5)
]

print("=== 多态演示 ===")
for shape in shapes:
    print_shape_info(shape)  # 同样的接口,不同的行为

高级面向对象特性

属性装饰器:智能属性访问

python 复制代码
class SmartProduct:
    def __init__(self, name, price):
        self.name = name
        self._price = price
        self._discount = 0
    
    @property
    def price(self):
        """获取价格(带折扣)"""
        return self._price * (1 - self._discount)
    
    @price.setter
    def price(self, value):
        """设置价格(带验证)"""
        if value < 0:
            raise ValueError("价格不能为负数")
        self._price = value
    
    @property
    def discount(self):
        """获取折扣"""
        return self._discount
    
    @discount.setter
    def discount(self, value):
        """设置折扣(带验证)"""
        if not 0 <= value <= 1:
            raise ValueError("折扣必须在0到1之间")
        self._discount = value
    
    @property
    def discounted_price(self):
        """计算折后价格(只读属性)"""
        return self._price * (1 - self._discount)

# 使用属性装饰器
product = SmartProduct("笔记本电脑", 6000)
print(f"原价: {product.price}")

product.discount = 0.1  # 设置9折
print(f"9折价格: {product.price}")
print(f"折后价格: {product.discounted_price}")

# product.price = -100  # 会抛出 ValueError

类方法和静态方法

python 复制代码
class DateUtils:
    """日期工具类"""
    
    # 类属性
    DATE_FORMAT = "YYYY-MM-DD"
    
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day
    
    @classmethod
    def from_string(cls, date_string):
        """类方法:从字符串创建对象"""
        year, month, day = map(int, date_string.split('-'))
        return cls(year, month, day)
    
    @classmethod
    def get_date_format(cls):
        """类方法:获取日期格式"""
        return cls.DATE_FORMAT
    
    @staticmethod
    def is_leap_year(year):
        """静态方法:判断是否是闰年(与类相关但不依赖实例)"""
        return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    
    def display(self):
        """实例方法"""
        return f"{self.year}-{self.month:02d}-{self.day:02d}"

# 使用不同方法
print("=== 方法类型演示 ===")

# 类方法使用
date1 = DateUtils.from_string("2024-01-15")
print(f"从字符串创建: {date1.display()}")
print(f"日期格式: {DateUtils.get_date_format()}")

# 静态方法使用
print(f"2024是闰年: {DateUtils.is_leap_year(2024)}")
print(f"2023是闰年: {DateUtils.is_leap_year(2023)}")

# 实例方法使用
date2 = DateUtils(2024, 12, 25)
print(f"直接创建: {date2.display()}")

实战:简易学生管理系统

python 复制代码
class Student:
    """学生类"""
    def __init__(self, student_id, name, age):
        self.student_id = student_id
        self.name = name
        self.age = age
        self.courses = []
    
    def enroll_course(self, course_name):
        """选课"""
        if course_name not in self.courses:
            self.courses.append(course_name)
            print(f"{self.name} 成功选修了 {course_name}")
        else:
            print(f"{self.name} 已经选修过 {course_name} 了")
    
    def drop_course(self, course_name):
        """退课"""
        if course_name in self.courses:
            self.courses.remove(course_name)
            print(f"{self.name} 成功退选了 {course_name}")
        else:
            print(f"{self.name} 没有选修 {course_name}")
    
    def display_info(self):
        """显示学生信息"""
        print(f"\n学生信息:")
        print(f"  学号: {self.student_id}")
        print(f"  姓名: {self.name}")
        print(f"  年龄: {self.age}")
        print(f"  选修课程: {', '.join(self.courses) if self.courses else '无'}")

class StudentManager:
    """学生管理器"""
    def __init__(self):
        self.students = {}
    
    def add_student(self, student_id, name, age):
        """添加学生"""
        if student_id in self.students:
            print(f"学号 {student_id} 已存在")
            return False
        
        self.students[student_id] = Student(student_id, name, age)
        print(f"成功添加学生: {name}")
        return True
    
    def remove_student(self, student_id):
        """删除学生"""
        if student_id in self.students:
            student_name = self.students[student_id].name
            del self.students[student_id]
            print(f"成功删除学生: {student_name}")
            return True
        else:
            print(f"学号 {student_id} 不存在")
            return False
    
    def find_student(self, student_id):
        """查找学生"""
        return self.students.get(student_id)
    
    def list_all_students(self):
        """列出所有学生"""
        if not self.students:
            print("还没有学生信息")
            return
        
        print("\n=== 所有学生信息 ===")
        for student in self.students.values():
            student.display_info()

# 使用学生管理系统
def demo_student_management():
    """演示学生管理系统"""
    manager = StudentManager()
    
    # 添加学生
    manager.add_student("S001", "张三", 20)
    manager.add_student("S002", "李四", 19)
    manager.add_student("S003", "王五", 21)
    
    # 学生选课
    zhang_san = manager.find_student("S001")
    if zhang_san:
        zhang_san.enroll_course("Python编程")
        zhang_san.enroll_course("数据结构")
        zhang_san.enroll_course("Python编程")  # 重复选课
    
    li_si = manager.find_student("S002")
    if li_si:
        li_si.enroll_course("Java编程")
        li_si.enroll_course("算法设计")
    
    # 显示所有学生
    manager.list_all_students()
    
    # 学生退课
    if zhang_san:
        zhang_san.drop_course("数据结构")
        zhang_san.drop_course("不存在的课程")  # 退选未选修的课程
    
    # 再次显示信息
    print("\n=== 退课后的信息 ===")
    manager.list_all_students()
    
    # 删除学生
    manager.remove_student("S003")
    manager.remove_student("S999")  # 删除不存在的学生
    
    # 最终学生列表
    print("\n=== 最终学生列表 ===")
    manager.list_all_students()

# 运行演示
demo_student_management()

面向对象设计原则

1. 单一职责原则

python 复制代码
# ✅ 好的设计:每个类只有一个职责
class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

class UserValidator:
    @staticmethod
    def validate_email(email):
        return "@" in email

class UserRepository:
    def save(self, user):
        print(f"保存用户 {user.name} 到数据库")

2. 开放封闭原则

python 复制代码
class Notification:
    def send(self, message):
        pass

class EmailNotification(Notification):
    def send(self, message):
        print(f"发送邮件: {message}")

class SMSNotification(Notification):
    def send(self, message):
        print(f"发送短信: {message}")

# 可以轻松添加新的通知方式,不需要修改现有代码
class WeChatNotification(Notification):
    def send(self, message):
        print(f"发送微信: {message}")

总结:从代码工人到架构师

面向对象编程的核心价值:让代码从"能工作"升级到"易维护、易扩展、易理解"。 记住这三个关键转变:

  1. 思维转变:从"怎么做"到"是什么" - 思考对象而不是步骤
  2. 封装思维:把相关的数据和行为组织在一起,隐藏内部细节
  3. 复用思维:通过继承和多态,避免重复造轮子
相关推荐
rising start1 小时前
五、python正则表达式
python·正则表达式
BBB努力学习程序设计1 小时前
Python错误处理艺术:从崩溃到优雅恢复的蜕变
python·pycharm
我叫黑大帅1 小时前
什么叫可迭代对象?为什么要用它?
前端·后端·python
Dillon Dong2 小时前
Django + uWSGI 部署至 Ubuntu 完整指南
python·ubuntu·django
k***82512 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
new_dev2 小时前
Python网络爬虫从入门到实战
爬虫·python·媒体
q***01652 小时前
Python爬虫完整代码拿走不谢
开发语言·爬虫·python
今天没有盐2 小时前
Python算法实战:从滑动窗口到数学可视化
python·pycharm·编程语言
Learn Beyond Limits3 小时前
Data Preprocessing|数据预处理
大数据·人工智能·python·ai·数据挖掘·数据处理