跳转至

面向对象编程基础

面向对象编程 (Object-Oriented Programming, OOP) 是一种编程范式,它将数据和操作数据的方法组织在“对象”中。

1. 类 (Class) 与 对象 (Object)

  • 类 (Class): 蓝图或模板。
  • 对象 (Object): 根据蓝图创建的具体实例。

举例

  • : "狗" (有名字,会叫)
  • 对象: 你的宠物狗 "旺财"

2. 定义类与创建对象

class Dog:
    # 类属性 (所有实例共享)
    species = "Canis familiaris"

    # 初始化方法 (构造函数)
    def __init__(self, name, age):
        # 实例属性 (每个对象独有)
        self.name = name
        self.age = age

    # 实例方法
    def bark(self):
        return f"{self.name} says Woof!"

    def description(self):
        return f"{self.name} is {self.age} years old."

# 创建对象 (实例化)
dog1 = Dog("Buddy", 3)
dog2 = Dog("Miles", 5)

# 访问属性
print(dog1.name)    # Buddy
print(dog1.species) # Canis familiaris

# 调用方法
print(dog1.bark())  # Buddy says Woof!

self 是什么?

self 代表实例本身。在类的方法中,第一个参数必须是 self (习惯用法,可以用其他名字但绝不建议)。通过 self.xxx,我们可以访问该实例的属性和方法。

3. 封装 (Encapsulation)

封装是指隐藏对象的内部实现细节。Python 没有严格的 private 关键字,而是依靠命名约定。

  • public: 普通属性,随处可访问 (e.g., self.name)。
  • protected: 单下划线 _var,暗示仅在内部或子类使用(非强制)。
  • private: 双下划线 __var,Python 会对其进行名称修饰 (Name Mangling),使外部难以直接访问。
class Account:
    def __init__(self, owner, balance):
        self.owner = owner       # Public
        self.__balance = balance # Private (私有)

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def get_balance(self):
        return self.__balance

# 外部访问
acc = Account("Alice", 1000)
# print(acc.__balance)  # ❌ 报错: AttributeError
print(acc.get_balance()) # ✅ 通过公开方法访问: 1000

4. 继承 (Inheritance)

子类可以继承父类的属性和方法,实现代码复用。

# 父类
class Animal:
    def speak(self):
        pass

# 子类
class Cat(Animal):
    def speak(self):
        return "Meow"

class Dog(Animal):
    def speak(self):
        return "Woof"

cat = Cat()
dog = Dog()

print(cat.speak()) # Meow
print(dog.speak()) # Woof

super() 函数

用于调用父类的方法,常用于扩充父类的 __init__

class Student(Person):
    def __init__(self, name, student_id):
        # 调用父类初始化
        super().__init__(name)
        self.student_id = student_id

5. 多态 (Polymorphism)

在 Python 中,多态意味着我们不关心对象具体的类型,只关心它的行为 (Duck Typing: 如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子)。

def make_noise(animal):
    print(animal.speak())

# 即使 Cat 和 Dog 是不同类,但都有 speak 方法
make_noise(cat)  # Meow
make_noise(dog)  # Woof

代码提示与类型检查

你可能会问:“我在写 animal. 的时候,编辑器会提示 speak 方法吗?”

  • 默认情况:Python 是动态类型的,编辑器在静态分析时不知道 animal 到底是什么类型,所以通常不会提示,也不会报错。如果你拼写错误写成了 animal.spek(),只有在程序运行到这一行时才会抛出 AttributeError

  • 类型注解 (Type Hints):为了获得更好的开发体验,现代 Python 推荐加上类型提示

    def make_noise(animal: Animal): # 告诉编辑器 animal 是 Animal 类型
        print(animal.speak())
    
    加上 : Animal 后,VS Code 等编辑器就能通过静态分析提供智能提示,并在你写错方法名时标红报错了。

6. 魔术方法 (Magic Methods)

以双下划线开头和结尾的方法,用于实现特定的 Python 行为(运算符重载等)。

方法 用途
__init__ 初始化对象
__str__ print(obj) 时显示的字符串 (面向用户)
__repr__ obj 在交互式模式显示的字符串 (面向开发者)
__len__ 实现 len(obj)
__add__ 实现 + 运算
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f"Vector({self.x}, {self.y})"

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

v1 = Vector(2, 4)
v2 = Vector(1, 1)
print(v1)       # Vector(2, 4)
print(v1 + v2)  # Vector(3, 5) -> 自动调用 __add__

本章小结

  • 是创建对象的工厂。
  • 使用 class Name: 定义类,__init__ 初始化。
  • 继承实现代码复用,多态提供接口一致性。
  • 双下划线 __var 实现简易私有化。
  • 魔术方法让自定义类拥有 Python 内置类型的行为。

练习题 (Final Challenge)

设计一个简易的 "图书馆管理系统"

  1. 定义 Book 类:包含 title, author, is_borrowed 属性。
  2. 定义 Library 类:包含一个书籍列表。
  3. 实现方法:
    • add_book(book): 添加新书。
    • borrow_book(title): 根据书名借书 (修改状态)。
    • return_book(title): 还书。
    • show_available(): 打印所有未借出的书。

基础篇完结!恭喜你打下了 Python 开发的坚实地基。 接下来建议进入进阶学习或开始实战项目。