面向对象编程基础
面向对象编程 (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)
设计一个简易的 "图书馆管理系统":
- 定义
Book类:包含title,author,is_borrowed属性。 - 定义
Library类:包含一个书籍列表。 - 实现方法:
add_book(book): 添加新书。borrow_book(title): 根据书名借书 (修改状态)。return_book(title): 还书。show_available(): 打印所有未借出的书。
基础篇完结!恭喜你打下了 Python 开发的坚实地基。 接下来建议进入进阶学习或开始实战项目。