Skip to content

🏗️ Python 面向对象编程

面向对象编程概述

面向对象编程(OOP)是一种编程范式,它将数据和操作数据的方法组织在一起,形成"对象"。Python 是完全面向对象的语言,一切皆对象。

OOP 的核心概念

  • 类(Class):对象的蓝图或模板
  • 对象(Object):类的实例
  • 属性(Attribute):对象的特征或数据
  • 方法(Method):对象的行为或功能
  • 封装(Encapsulation):隐藏内部实现细节
  • 继承(Inheritance):子类继承父类的特性
  • 多态(Polymorphism):同一接口,不同实现
💡 为什么使用 OOP?: - 代码复用:通过继承减少重复代码 - 模块化:将复杂问题分解为对象 - 维护性:修改一个类不影响其他类 - 扩展性:容易添加新功能

🏛️ 类和对象

基本类定义

python
class Person:
    """人类的基本定义"""
    
    # 类属性(所有实例共享)
    species = "智人"
    
    def __init__(self, name, age):
        """构造函数,初始化对象"""
        self.name = name  # 实例属性
        self.age = age
    
    def introduce(self):
        """自我介绍方法"""
        return f"你好,我是{self.name},今年{self.age}岁"
    
    def have_birthday(self):
        """过生日方法"""
        self.age += 1
        return f"{self.name}过生日了,现在{self.age}岁"

# 创建对象
person1 = Person("张三", 25)
person2 = Person("李四", 30)

# 使用对象
print(person1.introduce())
print(person2.have_birthday())
print(f"物种: {Person.species}")

属性和方法

python
class BankAccount:
    """银行账户类"""
    
    def __init__(self, account_number, initial_balance=0):
        self.account_number = account_number
        self.balance = initial_balance
        self.transaction_history = []
    
    def deposit(self, amount):
        """存款"""
        if amount > 0:
            self.balance += amount
            self.transaction_history.append(f"存款: +{amount}")
            return f"存款成功,余额: {self.balance}"
        else:
            return "存款金额必须大于0"
    
    def withdraw(self, amount):
        """取款"""
        if amount > 0 and amount <= self.balance:
            self.balance -= amount
            self.transaction_history.append(f"取款: -{amount}")
            return f"取款成功,余额: {self.balance}"
        else:
            return "取款失败,余额不足或金额无效"
    
    def get_balance(self):
        """查询余额"""
        return self.balance
    
    def get_history(self):
        """获取交易历史"""
        return self.transaction_history

# 使用银行账户
account = BankAccount("123456789", 1000)
print(account.deposit(500))
print(account.withdraw(200))
print(f"当前余额: {account.get_balance()}")
print(f"交易历史: {account.get_history()}")

🔒 封装

私有属性和方法

python
class Student:
    """学生类,演示封装"""
    
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
        self.__grade = 0  # 私有属性,使用双下划线
        self.__attendance = 0
    
    def set_grade(self, grade):
        """设置成绩(带验证)"""
        if 0 <= grade <= 100:
            self.__grade = grade
            return "成绩设置成功"
        else:
            return "成绩必须在0-100之间"
    
    def get_grade(self):
        """获取成绩"""
        return self.__grade
    
    def add_attendance(self):
        """增加出勤"""
        self.__attendance += 1
    
    def get_attendance(self):
        """获取出勤次数"""
        return self.__attendance
    
    def get_status(self):
        """获取学生状态"""
        if self.__grade >= 60 and self.__attendance >= 20:
            return "合格"
        else:
            return "需要努力"

# 使用学生类
student = Student("王五", "2023001")
print(student.set_grade(85))
print(student.get_grade())
student.add_attendance()
print(f"出勤次数: {student.get_attendance()}")
print(f"学生状态: {student.get_status()}")

# 尝试访问私有属性(不推荐)
# print(student.__grade)  # 这会报错

属性装饰器

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("温度不能低于绝对零度")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        """华氏度属性(只读)"""
        return self._celsius * 9/5 + 32
    
    @property
    def kelvin(self):
        """开尔文属性(只读)"""
        return self._celsius + 273.15

# 使用温度类
temp = Temperature(25)
print(f"摄氏度: {temp.celsius}")
print(f"华氏度: {temp.fahrenheit}")
print(f"开尔文: {temp.kelvin}")

temp.celsius = 30
print(f"新的摄氏度: {temp.celsius}")

👨‍👩‍👧‍👦 继承

基本继承

python
class Animal:
    """动物基类"""
    
    def __init__(self, name, species):
        self.name = name
        self.species = species
    
    def make_sound(self):
        """发出声音"""
        return f"{self.name}发出了声音"
    
    def eat(self):
        """吃东西"""
        return f"{self.name}在吃东西"

class Dog(Animal):
    """狗类,继承自动物"""
    
    def __init__(self, name, breed):
        super().__init__(name, "狗")  # 调用父类构造函数
        self.breed = breed
    
    def make_sound(self):
        """重写父类方法"""
        return f"{self.name}汪汪叫"
    
    def fetch(self):
        """狗特有的方法"""
        return f"{self.name}去捡球了"

class Cat(Animal):
    """猫类,继承自动物"""
    
    def __init__(self, name, color):
        super().__init__(name, "猫")
        self.color = color
    
    def make_sound(self):
        """重写父类方法"""
        return f"{self.name}喵喵叫"
    
    def climb(self):
        """猫特有的方法"""
        return f"{self.name}爬树了"

# 使用继承
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "橘色")

print(dog.make_sound())
print(cat.make_sound())
print(dog.fetch())
print(cat.climb())

多重继承

python
class Flyable:
    """可飞行接口"""
    
    def fly(self):
        return "正在飞行"

class Swimmable:
    """可游泳接口"""
    
    def swim(self):
        return "正在游泳"

class Duck(Animal, Flyable, Swimmable):
    """鸭子类,多重继承"""
    
    def __init__(self, name):
        super().__init__(name, "鸭子")
    
    def make_sound(self):
        return f"{self.name}嘎嘎叫"

# 使用多重继承
duck = Duck("唐老鸭")
print(duck.make_sound())
print(duck.fly())
print(duck.swim())

方法重写和 super()

python
class Vehicle:
    """交通工具基类"""
    
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model
        self.speed = 0
    
    def start(self):
        return f"{self.brand} {self.model} 启动了"
    
    def accelerate(self, increment):
        self.speed += increment
        return f"加速到 {self.speed} km/h"

class Car(Vehicle):
    """汽车类"""
    
    def __init__(self, brand, model, fuel_type):
        super().__init__(brand, model)  # 调用父类构造函数
        self.fuel_type = fuel_type
        self.doors = 4
    
    def start(self):
        # 调用父类方法并扩展
        base_start = super().start()
        return f"{base_start},使用{self.fuel_type}燃料"
    
    def open_trunk(self):
        return f"{self.brand} {self.model} 打开了后备箱"

# 使用重写
car = Car("丰田", "凯美瑞", "汽油")
print(car.start())
print(car.accelerate(20))
print(car.open_trunk())

🎭 多态

多态示例

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

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 3.14159 * self.radius ** 2
    
    def perimeter(self):
        return 2 * 3.14159 * self.radius

class Triangle(Shape):
    """三角形类"""
    
    def __init__(self, base, height, side1, side2):
        self.base = base
        self.height = height
        self.side1 = side1
        self.side2 = side2
    
    def area(self):
        return 0.5 * self.base * self.height
    
    def perimeter(self):
        return self.base + self.side1 + self.side2

# 多态演示
def calculate_shape_info(shape):
    """计算形状信息的函数(多态)"""
    return f"面积: {shape.area():.2f}, 周长: {shape.perimeter():.2f}"

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

# 使用多态
for shape in shapes:
    print(f"{shape.__class__.__name__}: {calculate_shape_info(shape)}")

🏭 抽象基类

python
from abc import ABC, abstractmethod

class Animal(ABC):
    """抽象动物类"""
    
    def __init__(self, name):
        self.name = name
    
    @abstractmethod
    def make_sound(self):
        """抽象方法,子类必须实现"""
        pass
    
    def eat(self):
        """具体方法,子类可以继承"""
        return f"{self.name}在吃东西"

class Dog(Animal):
    """狗类,实现抽象方法"""
    
    def make_sound(self):
        return f"{self.name}汪汪叫"

class Cat(Animal):
    """猫类,实现抽象方法"""
    
    def make_sound(self):
        return f"{self.name}喵喵叫"

# 使用抽象基类
dog = Dog("旺财")
cat = Cat("咪咪")

print(dog.make_sound())
print(cat.make_sound())
print(dog.eat())

🎯 特殊方法(魔术方法)

python
class Book:
    """图书类,演示特殊方法"""
    
    def __init__(self, title, author, pages):
        self.title = title
        self.author = author
        self.pages = pages
    
    def __str__(self):
        """字符串表示"""
        return f"《{self.title}》- {self.author}"
    
    def __repr__(self):
        """开发者表示"""
        return f"Book('{self.title}', '{self.author}', {self.pages})"
    
    def __len__(self):
        """长度"""
        return self.pages
    
    def __eq__(self, other):
        """相等比较"""
        if isinstance(other, Book):
            return self.title == other.title and self.author == other.author
        return False
    
    def __lt__(self, other):
        """小于比较"""
        if isinstance(other, Book):
            return self.pages < other.pages
        return NotImplemented
    
    def __add__(self, other):
        """加法运算"""
        if isinstance(other, Book):
            return Book(f"{self.title} & {other.title}", 
                       f"{self.author} & {other.author}", 
                       self.pages + other.pages)
        return NotImplemented

# 使用特殊方法
book1 = Book("Python编程", "张三", 300)
book2 = Book("Java编程", "李四", 250)

print(str(book1))  # 使用 __str__
print(repr(book1))  # 使用 __repr__
print(len(book1))  # 使用 __len__
print(book1 == book2)  # 使用 __eq__
print(book1 < book2)  # 使用 __lt__
print(book1 + book2)  # 使用 __add__

🎯 实践练习

练习1:图书馆管理系统

设计一个图书馆管理系统,包含以下类:

  • Book(图书类):书名、作者、ISBN、借阅状态
  • Library(图书馆类):图书列表、借书、还书功能
  • Member(会员类):姓名、会员号、借阅历史

练习2:银行账户系统

扩展银行账户类,添加:

  • 不同类型的账户(储蓄账户、支票账户)
  • 利息计算
  • 账户转账功能
  • 账户历史记录

练习3:游戏角色系统

设计一个游戏角色系统:

  • Character(角色基类):生命值、攻击力、防御力
  • Warrior(战士类):高攻击力
  • Mage(法师类):魔法攻击
  • Archer(弓箭手类):远程攻击

练习4:学生成绩管理系统

创建一个完整的学生成绩管理系统:

  • Student(学生类)
  • Course(课程类)
  • Grade(成绩类)
  • GradeManager(成绩管理类)

🔧 设计模式

单例模式

python
class Singleton:
    """单例模式"""
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.initialized = True
            self.data = []

# 使用单例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True,同一个实例

工厂模式

python
class AnimalFactory:
    """动物工厂"""
    
    @staticmethod
    def create_animal(animal_type, name):
        if animal_type == "dog":
            return Dog(name, "未知品种")
        elif animal_type == "cat":
            return Cat(name, "未知颜色")
        else:
            raise ValueError(f"未知的动物类型: {animal_type}")

# 使用工厂模式
dog = AnimalFactory.create_animal("dog", "旺财")
cat = AnimalFactory.create_animal("cat", "咪咪")

📊 类的关系

类的关系类型

  1. 继承关系(is-a):子类是父类的一种
  2. 组合关系(has-a):一个类包含另一个类的对象
  3. 聚合关系(part-of):整体与部分的关系
  4. 依赖关系(uses-a):一个类使用另一个类
python
# 组合关系示例
class Engine:
    def start(self):
        return "引擎启动"

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

# 使用组合
car = Car()
print(car.start())

下一步

现在你已经掌握了 Python 的面向对象编程,接下来学习:


💡 学习建议:多练习设计类的关系,理解面向对象的设计思想