Skip to content

Python 面向对象编程

面向对象编程(Object-Oriented Programming,简称 OOP)是一种编程范式,它将数据和操作数据的方法封装在一起,形成对象。本章节将详细介绍 Python 中的面向对象编程概念和实践。

基本概念

类(Class)

类是对象的蓝图或模板,定义了对象的属性和方法。

对象(Object)

对象是类的实例,具有类定义的属性和方法。

属性(Attribute)

属性是对象的特征,如颜色、大小等。

方法(Method)

方法是对象的行为,如移动、计算等。

继承(Inheritance)

继承是指一个类可以继承另一个类的属性和方法。

多态(Polymorphism)

多态是指不同类的对象可以响应相同的方法调用,但行为不同。

封装(Encapsulation)

封装是指将数据和方法封装在类中,对外部隐藏实现细节。

抽象(Abstraction)

抽象是指只暴露必要的接口,隐藏不必要的细节。

类的定义

基本语法

python
class ClassName:
    # 类变量
    class_variable = value
    
    # 初始化方法
    def __init__(self, parameter1, parameter2, ...):
        # 实例变量
        self.instance_variable1 = parameter1
        self.instance_variable2 = parameter2
        ...
    
    # 实例方法
    def method_name(self, parameter1, parameter2, ...):
        # 方法体
        ...
    
    # 类方法
    @classmethod
    def class_method(cls, parameter1, parameter2, ...):
        # 方法体
        ...
    
    # 静态方法
    @staticmethod
    def static_method(parameter1, parameter2, ...):
        # 方法体
        ...

示例 1:简单类

python
# 简单类
class Person:
    """Person 类"""
    
    # 类变量
    species = "人类"
    
    # 初始化方法
    def __init__(self, name, age):
        """初始化方法"""
        self.name = name  # 实例变量
        self.age = age    # 实例变量
    
    # 实例方法
    def greet(self):
        """问候方法"""
        print(f"你好,我是 {self.name},今年 {self.age} 岁。")
    
    # 实例方法
    def celebrate_birthday(self):
        """庆祝生日方法"""
        self.age += 1
        print(f"生日快乐!现在 {self.name}{self.age} 岁了。")

# 创建对象
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# 访问类变量
print(f"person1 的物种:{person1.species}")
print(f"person2 的物种:{person2.species}")
print(f"Person 类的物种:{Person.species}")

# 访问实例变量
print(f"person1 的名字:{person1.name}")
print(f"person1 的年龄:{person1.age}")
print(f"person2 的名字:{person2.name}")
print(f"person2 的年龄:{person2.age}")

# 调用实例方法
person1.greet()
person2.greet()

# 调用方法修改属性
person1.celebrate_birthday()
print(f"person1 的年龄:{person1.age}")

输出:

person1 的物种:人类
person2 的物种:人类
Person 类的物种:人类
person1 的名字:Alice
person1 的年龄:30
person2 的名字:Bob
person2 的年龄:25
你好,我是 Alice,今年 30 岁。
你好,我是 Bob,今年 25 岁。
生日快乐!现在 Alice 是 31 岁了。
person1 的年龄:31

示例 2:类方法和静态方法

python
# 类方法和静态方法
class MathUtils:
    """数学工具类"""
    
    # 类变量
    PI = 3.14159
    
    # 初始化方法
    def __init__(self, radius):
        """初始化方法"""
        self.radius = radius
    
    # 实例方法
    def calculate_circle_area(self):
        """计算圆的面积"""
        return self.PI * self.radius ** 2
    
    # 类方法
    @classmethod
    def set_pi(cls, value):
        """设置 PI 的值"""
        cls.PI = value
        print(f"PI 的值已设置为:{cls.PI}")
    
    # 静态方法
    @staticmethod
    def add(a, b):
        """计算两个数的和"""
        return a + b
    
    # 静态方法
    @staticmethod
    def multiply(a, b):
        """计算两个数的乘积"""
        return a * b

# 使用实例方法
math_obj = MathUtils(5)
area = math_obj.calculate_circle_area()
print(f"圆的面积:{area}")

# 使用类方法
MathUtils.set_pi(3.14)
area = math_obj.calculate_circle_area()
print(f"更新 PI 后圆的面积:{area}")

# 使用静态方法
print(f"2 + 3 = {MathUtils.add(2, 3)}")
print(f"2 * 3 = {MathUtils.multiply(2, 3)}")

输出:

圆的面积:78.53975
PI 的值已设置为:3.14
更新 PI 后圆的面积:78.5
2 + 3 = 5
2 * 3 = 6

继承

基本语法

python
class ParentClass:
    # 父类定义
    pass

class ChildClass(ParentClass):
    # 子类定义
    pass

示例 1:单继承

python
# 单继承
class Animal:
    """动物类"""
    
    def __init__(self, name):
        """初始化方法"""
        self.name = name
    
    def speak(self):
        """说话方法"""
        print(f"{self.name} 发出声音。")

class Dog(Animal):
    """狗类"""
    
    def speak(self):
        """重写说话方法"""
        print(f"{self.name} 汪汪叫。")

class Cat(Animal):
    """猫类"""
    
    def speak(self):
        """重写说话方法"""
        print(f"{self.name} 喵喵叫。")

# 创建对象
animal = Animal("动物")
dog = Dog("小狗")
cat = Cat("小猫")

# 调用方法
animal.speak()
dog.speak()
cat.speak()

输出:

动物 发出声音。
小狗 汪汪叫。
小猫 喵喵叫。

示例 2:多继承

python
# 多继承
class A:
    """类 A"""
    
    def method_a(self):
        """方法 A"""
        print("方法 A")

class B:
    """类 B"""
    
    def method_b(self):
        """方法 B"""
        print("方法 B")

class C(A, B):
    """类 C,继承自 A 和 B"""
    
    def method_c(self):
        """方法 C"""
        print("方法 C")

# 创建对象
c = C()

# 调用继承的方法
c.method_a()
c.method_b()

# 调用自己的方法
c.method_c()

输出:

方法 A
方法 B
方法 C

示例 3:super() 函数

python
# super() 函数
class Parent:
    """父类"""
    
    def __init__(self, name):
        """初始化方法"""
        self.name = name
        print(f"父类初始化:{self.name}")
    
    def method(self):
        """父类方法"""
        print(f"父类方法:{self.name}")

class Child(Parent):
    """子类"""
    
    def __init__(self, name, age):
        """初始化方法"""
        super().__init__(name)  # 调用父类的初始化方法
        self.age = age
        print(f"子类初始化:{self.name}, {self.age}")
    
    def method(self):
        """子类方法"""
        super().method()  # 调用父类的方法
        print(f"子类方法:{self.name}, {self.age}")

# 创建对象
child = Child("Alice", 30)

# 调用方法
child.method()

输出:

父类初始化:Alice
子类初始化:Alice, 30
父类方法:Alice
子类方法:Alice, 30

多态

示例

python
# 多态
class Animal:
    """动物类"""
    
    def speak(self):
        """说话方法"""
        pass

class Dog(Animal):
    """狗类"""
    
    def speak(self):
        """重写说话方法"""
        return "汪汪叫"

class Cat(Animal):
    """猫类"""
    
    def speak(self):
        """重写说话方法"""
        return "喵喵叫"

class Cow(Animal):
    """牛类"""
    
    def speak(self):
        """重写说话方法"""
        return "哞哞叫"

# 多态函数
def animal_speak(animal):
    """动物说话函数"""
    print(f"动物说:{animal.speak()}")

# 创建对象
dog = Dog()
cat = Cat()
cow = Cow()

# 调用多态函数
animal_speak(dog)
animal_speak(cat)
animal_speak(cow)

输出:

动物说:汪汪叫
动物说:喵喵叫
动物说:哞哞叫

封装

私有属性和方法

在 Python 中,使用双下划线 __ 前缀来定义私有属性和方法。

示例

python
# 封装
class Person:
    """Person 类"""
    
    def __init__(self, name, age, salary):
        """初始化方法"""
        self.name = name        # 公开属性
        self._age = age         # 受保护属性
        self.__salary = salary  # 私有属性
    
    def get_salary(self):
        """获取工资(公开方法)"""
        return self.__salary
    
    def set_salary(self, salary):
        """设置工资(公开方法)"""
        if salary > 0:
            self.__salary = salary
        else:
            print("工资不能为负数")
    
    def __private_method(self):
        """私有方法"""
        print("这是一个私有方法")
    
    def public_method(self):
        """公开方法"""
        print("这是一个公开方法")
        self.__private_method()  # 在类内部可以访问私有方法

# 创建对象
person = Person("Alice", 30, 5000)

# 访问公开属性
print(f"姓名:{person.name}")

# 访问受保护属性(不推荐)
print(f"年龄:{person._age}")

# 尝试访问私有属性(会失败)
try:
    print(f"工资:{person.__salary}")
except AttributeError as e:
    print(f"错误:{e}")

# 通过公开方法访问私有属性
print(f"工资:{person.get_salary()}")

# 通过公开方法修改私有属性
person.set_salary(6000)
print(f"新工资:{person.get_salary()}")

# 尝试访问私有方法(会失败)
try:
    person.__private_method()
except AttributeError as e:
    print(f"错误:{e}")

# 通过公开方法调用私有方法
person.public_method()

输出:

姓名:Alice
年龄:30
错误:'Person' object has no attribute '__salary'
工资:5000
新工资:6000
错误:'Person' object has no attribute '__private_method'
这是一个公开方法
这是一个私有方法

特殊方法

Python 中有许多特殊方法,它们以双下划线 __ 开头和结尾,用于实现对象的特殊行为。

常见特殊方法

特殊方法描述
__init__初始化方法
__str__字符串表示方法
__repr__官方字符串表示方法
__len__长度方法
__getitem__获取元素方法
__setitem__设置元素方法
__delitem__删除元素方法
__iter__迭代器方法
__next__下一个元素方法
__add__加法方法
__sub__减法方法
__mul__乘法方法
__truediv__除法方法
__eq__等于方法
__ne__不等于方法
__lt__小于方法
__le__小于等于方法
__gt__大于方法
__ge__大于等于方法
__contains__包含方法

示例:自定义列表类

python
# 自定义列表类
class MyList:
    """自定义列表类"""
    
    def __init__(self, *args):
        """初始化方法"""
        self.items = list(args)
    
    def __str__(self):
        """字符串表示方法"""
        return f"MyList({self.items})"
    
    def __repr__(self):
        """官方字符串表示方法"""
        return f"MyList({self.items})"
    
    def __len__(self):
        """长度方法"""
        return len(self.items)
    
    def __getitem__(self, index):
        """获取元素方法"""
        return self.items[index]
    
    def __setitem__(self, index, value):
        """设置元素方法"""
        self.items[index] = value
    
    def __delitem__(self, index):
        """删除元素方法"""
        del self.items[index]
    
    def __iter__(self):
        """迭代器方法"""
        return iter(self.items)
    
    def __add__(self, other):
        """加法方法"""
        if isinstance(other, MyList):
            return MyList(*(self.items + other.items))
        elif isinstance(other, list):
            return MyList(*(self.items + other))
        else:
            raise TypeError("不支持的操作数类型")
    
    def __contains__(self, item):
        """包含方法"""
        return item in self.items
    
    def append(self, item):
        """追加方法"""
        self.items.append(item)
    
    def remove(self, item):
        """移除方法"""
        self.items.remove(item)

# 创建对象
my_list = MyList(1, 2, 3, 4, 5)
print(f"my_list: {my_list}")

# 测试长度方法
print(f"长度: {len(my_list)}")

# 测试获取元素方法
print(f"第一个元素: {my_list[0]}")
print(f"最后一个元素: {my_list[-1]}")

# 测试设置元素方法
my_list[0] = 10
print(f"修改后: {my_list}")

# 测试删除元素方法
del my_list[4]
print(f"删除后: {my_list}")

# 测试迭代
print("迭代:")
for item in my_list:
    print(item)

# 测试加法
my_list2 = MyList(6, 7, 8)
result = my_list + my_list2
print(f"加法结果: {result}")

# 测试包含
print(f"3 在 my_list 中: {3 in my_list}")
print(f"100 在 my_list 中: {100 in my_list}")

# 测试其他方法
my_list.append(9)
print(f"追加后: {my_list}")

my_list.remove(2)
print(f"移除后: {my_list}")

输出:

my_list: MyList([1, 2, 3, 4, 5])
长度: 5
第一个元素: 1
最后一个元素: 5
修改后: MyList([10, 2, 3, 4, 5])
删除后: MyList([10, 2, 3, 4])
迭代:
10
2
3
4
加法结果: MyList([10, 2, 3, 4, 6, 7, 8])
3 在 my_list 中: True
100 在 my_list 中: False
追加后: MyList([10, 2, 3, 4, 9])
移除后: MyList([10, 3, 4, 9])

抽象类

抽象类是不能实例化的类,用于定义接口。在 Python 中,使用 abc 模块来创建抽象类。

示例

python
# 抽象类
from abc import ABC, abstractmethod

class Shape(ABC):
    """形状抽象类"""
    
    @abstractmethod
    def calculate_area(self):
        """计算面积(抽象方法)"""
        pass
    
    @abstractmethod
    def calculate_perimeter(self):
        """计算周长(抽象方法)"""
        pass

class Circle(Shape):
    """圆形类"""
    
    def __init__(self, radius):
        """初始化方法"""
        self.radius = radius
    
    def calculate_area(self):
        """计算面积"""
        import math
        return math.pi * self.radius ** 2
    
    def calculate_perimeter(self):
        """计算周长"""
        import math
        return 2 * math.pi * self.radius

class Rectangle(Shape):
    """矩形类"""
    
    def __init__(self, length, width):
        """初始化方法"""
        self.length = length
        self.width = width
    
    def calculate_area(self):
        """计算面积"""
        return self.length * self.width
    
    def calculate_perimeter(self):
        """计算周长"""
        return 2 * (self.length + self.width)

# 尝试实例化抽象类(会失败)
try:
    shape = Shape()
except TypeError as e:
    print(f"错误:{e}")

# 创建子类对象
circle = Circle(5)
print(f"圆形面积:{circle.calculate_area():.2f}")
print(f"圆形周长:{circle.calculate_perimeter():.2f}")

rectangle = Rectangle(4, 6)
print(f"矩形面积:{rectangle.calculate_area()}")
print(f"矩形周长:{rectangle.calculate_perimeter()}")

输出:

错误:Can't instantiate abstract class Shape with abstract methods calculate_area, calculate_perimeter
圆形面积:78.54
圆形周长:31.42
矩形面积:24
矩形周长:20

实际应用示例

示例 1:学生管理系统

python
# 学生管理系统
class Student:
    """学生类"""
    
    def __init__(self, id, name, age, grade):
        """初始化方法"""
        self.id = id
        self.name = name
        self.age = age
        self.grade = grade
    
    def __str__(self):
        """字符串表示方法"""
        return f"ID: {self.id}, 姓名: {self.name}, 年龄: {self.age}, 成绩: {self.grade}"

class StudentManager:
    """学生管理类"""
    
    def __init__(self):
        """初始化方法"""
        self.students = []
    
    def add_student(self, student):
        """添加学生"""
        self.students.append(student)
        print(f"添加学生成功:{student.name}")
    
    def remove_student(self, student_id):
        """删除学生"""
        for student in self.students:
            if student.id == student_id:
                self.students.remove(student)
                print(f"删除学生成功:{student.name}")
                return True
        print(f"学生 ID {student_id} 不存在")
        return False
    
    def find_student(self, student_id):
        """查找学生"""
        for student in self.students:
            if student.id == student_id:
                return student
        return None
    
    def list_students(self):
        """列出所有学生"""
        if not self.students:
            print("没有学生记录")
            return
        print("学生列表:")
        for student in self.students:
            print(student)
    
    def update_student(self, student_id, **kwargs):
        """更新学生信息"""
        student = self.find_student(student_id)
        if student:
            for key, value in kwargs.items():
                if hasattr(student, key):
                    setattr(student, key, value)
            print(f"更新学生成功:{student.name}")
            return True
        print(f"学生 ID {student_id} 不存在")
        return False

# 测试
manager = StudentManager()

# 添加学生
student1 = Student(1, "Alice", 18, 95)
student2 = Student(2, "Bob", 17, 88)
student3 = Student(3, "Charlie", 19, 92)

manager.add_student(student1)
manager.add_student(student2)
manager.add_student(student3)

# 列出学生
print("\n列出所有学生:")
manager.list_students()

# 查找学生
print("\n查找学生:")
found = manager.find_student(2)
if found:
    print(f"找到学生:{found}")
else:
    print("学生不存在")

# 更新学生
print("\n更新学生:")
manager.update_student(2, age=18, grade=90)

# 列出学生
print("\n列出所有学生:")
manager.list_students()

# 删除学生
print("\n删除学生:")
manager.remove_student(3)

# 列出学生
print("\n列出所有学生:")
manager.list_students()

输出:

添加学生成功:Alice
添加学生成功:Bob
添加学生成功:Charlie

列出所有学生:
学生列表:
ID: 1, 姓名: Alice, 年龄: 18, 成绩: 95
ID: 2, 姓名: Bob, 年龄: 17, 成绩: 88
ID: 3, 姓名: Charlie, 年龄: 19, 成绩: 92

查找学生:
找到学生:ID: 2, 姓名: Bob, 年龄: 17, 成绩: 88

更新学生:
更新学生成功:Bob

列出所有学生:
学生列表:
ID: 1, 姓名: Alice, 年龄: 18, 成绩: 95
ID: 2, 姓名: Bob, 年龄: 18, 成绩: 90
ID: 3, 姓名: Charlie, 年龄: 19, 成绩: 92

删除学生:
删除学生成功:Charlie

列出所有学生:
学生列表:
ID: 1, 姓名: Alice, 年龄: 18, 成绩: 95
ID: 2, 姓名: Bob, 年龄: 18, 成绩: 90

示例 2:银行账户系统

python
# 银行账户系统
class Account:
    """账户基类"""
    
    def __init__(self, account_number, balance=0):
        """初始化方法"""
        self.account_number = account_number
        self.balance = balance
    
    def deposit(self, amount):
        """存款"""
        if amount > 0:
            self.balance += amount
            print(f"存款成功:{amount} 元")
            print(f"当前余额:{self.balance} 元")
        else:
            print("存款金额必须大于 0")
    
    def withdraw(self, amount):
        """取款"""
        if amount > 0:
            if amount <= self.balance:
                self.balance -= amount
                print(f"取款成功:{amount} 元")
                print(f"当前余额:{self.balance} 元")
            else:
                print("余额不足")
        else:
            print("取款金额必须大于 0")
    
    def get_balance(self):
        """获取余额"""
        return self.balance
    
    def __str__(self):
        """字符串表示方法"""
        return f"账户号:{self.account_number}, 余额:{self.balance} 元"

class SavingsAccount(Account):
    """储蓄账户"""
    
    def __init__(self, account_number, balance=0, interest_rate=0.01):
        """初始化方法"""
        super().__init__(account_number, balance)
        self.interest_rate = interest_rate
    
    def add_interest(self):
        """添加利息"""
        interest = self.balance * self.interest_rate
        self.balance += interest
        print(f"添加利息:{interest:.2f} 元")
        print(f"当前余额:{self.balance:.2f} 元")
    
    def __str__(self):
        """字符串表示方法"""
        return f"储蓄账户 - 账户号:{self.account_number}, 余额:{self.balance} 元, 利率:{self.interest_rate:.2%}"

class CheckingAccount(Account):
    """支票账户"""
    
    def __init__(self, account_number, balance=0, overdraft_limit=1000):
        """初始化方法"""
        super().__init__(account_number, balance)
        self.overdraft_limit = overdraft_limit
    
    def withdraw(self, amount):
        """取款(支持透支)"""
        if amount > 0:
            if amount <= self.balance + self.overdraft_limit:
                self.balance -= amount
                print(f"取款成功:{amount} 元")
                print(f"当前余额:{self.balance} 元")
            else:
                print(f"超过透支限额,最大可取:{self.balance + self.overdraft_limit} 元")
        else:
            print("取款金额必须大于 0")
    
    def __str__(self):
        """字符串表示方法"""
        return f"支票账户 - 账户号:{self.account_number}, 余额:{self.balance} 元, 透支限额:{self.overdraft_limit} 元"

# 测试
print("=== 储蓄账户 ===")
savings = SavingsAccount("SA123", 10000)
print(savings)
savings.deposit(5000)
savings.withdraw(2000)
savings.add_interest()

print("\n=== 支票账户 ===")
checking = CheckingAccount("CA456", 5000, 2000)
print(checking)
checking.deposit(1000)
checking.withdraw(8000)  # 测试透支
checking.withdraw(1000)  # 再次取款

输出:

=== 储蓄账户 ===
储蓄账户 - 账户号:SA123, 余额:10000 元, 利率:1.00%
存款成功:5000 元
当前余额:15000 元
取款成功:2000 元
当前余额:13000 元
添加利息:130.00 元
当前余额:13130.00 元

=== 支票账户 ===
支票账户 - 账户号:CA456, 余额:5000 元, 透支限额:2000 元
存款成功:1000 元
当前余额:6000 元
取款成功:8000 元
当前余额:-2000 元
取款成功:1000 元
当前余额:-3000 元

总结

面向对象编程是 Python 中的重要编程范式,本章节介绍了:

  1. 基本概念:类、对象、属性、方法、继承、多态、封装、抽象
  2. 类的定义:实例变量、类变量、实例方法、类方法、静态方法
  3. 继承:单继承、多继承、super() 函数
  4. 多态:不同类的对象响应相同的方法调用
  5. 封装:私有属性和方法
  6. 特殊方法__init____str____len__
  7. 抽象类:使用 abc 模块创建抽象类
  8. 实际应用示例:学生管理系统、银行账户系统

通过面向对象编程,可以使代码更加模块化、可维护和可扩展。掌握面向对象编程的概念和技巧,对于编写复杂的 Python 程序非常重要。