目录
一、面向对象基础概念
1.1 类(Class)与对象(Object)
概念解析:
类(Class)是对象的抽象蓝图,定义了对象的属性和方法。它描述一类事物的共同特征,就像建筑的设计图纸。对象(Object)是类的具体实例,就像根据图纸建造的实际建筑。
设计要点:
- 类名称使用大驼峰命名法(如
Car
,BankAccount
) __init__
方法用于初始化实例属性- 实例方法用于定义对象行为
class Vehicle:
"""交通工具类(抽象概念)"""
# 类属性(所有实例共享)
category = "交通工具"
def __init__(self, brand, color):
"""构造方法初始化实例属性"""
self.brand = brand # 实例属性:品牌
self.color = color # 实例属性:颜色
self.speed = 0 # 实例属性:当前速度
def accelerate(self, increment):
"""加速方法"""
self.speed += increment
return f"加速到 {self.speed} km/h"
# 创建两个不同车辆对象
tesla = Vehicle("Tesla", "红色")
bmw = Vehicle("BMW", "蓝色")
# 验证类与对象关系
print(f"对象类型: {type(tesla)}") # <class '__main__.Vehicle'>
print(f"类属性访问: {tesla.category}") # 交通工具(所有实例共享)
print(f"实例属性: {tesla.color}{tesla.brand}") # 红色Tesla
print(f"不同实例属性: {bmw.color}{bmw.brand}") # 蓝色BMW
print(tesla.accelerate(30)) # 加速到 30 km/h
1.2 对象(Object)
# 创建不同实例
pc1 = Computer("Dell")
pc2 = Computer("HP")
# 测试对象概念
print(pc1.brand) # "Dell"
print(pc2.brand) # "HP" - 相同类的不同实例
1.3 类与对象关系
"""
类:模版(定义属性和方法)
对象:根据模版创建的具体实例
"""
# 测试关系
print(pc1.__class__ == Computer) # True
二、三大核心特性
2.1 封装(Encapsulation)
概念解析:
封装是把数据和对数据的操作(方法)捆绑在一起的过程,同时限制对外部的访问。它通过访问控制保护对象内部状态,只允许通过定义好的接口与对象交互。
实现策略:
- 公有成员:无特殊前缀,可自由访问
- 私有成员:双下划线前缀
__private_var
,仅类内访问 - 保护成员:单下划线前缀
_protected_var
,类内和子类访问
class BankAccount:
"""银行账户(封装范例)"""
def __init__(self, account_name):
# 私有属性(封装保护)
self.__balance = 0
self.account_name = account_name
# 公开方法访问私有属性
def deposit(self, amount):
"""存款(包含业务逻辑验证)"""
if amount <= 0:
return "存款金额必须大于0"
self.__balance += amount
return f"成功存入 ¥{amount}"
# 公开方法获取私有属性
def get_balance(self):
"""获取余额(访问器方法)"""
return f"当前余额: ¥{self.__balance}"
# 公开方法操作私有属性
def withdraw(self, amount):
"""取款(包含业务逻辑验证)"""
if amount > self.__balance:
return "余额不足"
self.__balance -= amount
return f"成功取出 ¥{amount}"
# 创建账户
account = BankAccount("张三账户")
# 测试存款取款
print(account.deposit(500)) # 成功存入 ¥500
print(account.get_balance()) # 当前余额: ¥500
print(account.withdraw(200)) # 成功取出 ¥200
print(account.get_balance()) # 当前余额: ¥300
# 测试直接访问私有属性(应失败)
try:
print(account.__balance) # 直接访问私有属性
except AttributeError as e:
print(f"封装保护生效: {e}") # 'BankAccount' object has no attribute '__balance'
# 测试绕过封装的访问(不推荐但可能)
print("绕过封装访问:", account._BankAccount__balance) # 300(实际代码不要这样用)
2.2 继承(Inheritance)
概念解析:
继承是面向对象编程中类的扩展机制,允许子类复用父类的属性和方法。分为:
- 单继承:一个子类继承一个父类
- 多继承:一个子类继承多个父类
- MRO(方法解析顺序):Python使用C3算法解决多继承中的方法冲突
class Animal:
"""动物基类"""
def __init__(self, name):
self.name = name
def speak(self):
return "动物叫声"
def eat(self):
return "吃东西"
class Dog(Animal): # 单继承
"""狗类(继承自动物)"""
def speak(self): # 方法重写(多态基础)
return "汪汪!"
def fetch(self): # 扩展新方法
return "叼回飞盘"
class Robot:
"""机器人类"""
def action(self):
return "执行任务"
class RoboDog(Dog, Robot): # 多继承
"""机器狗类(继承自Dog和Robot)"""
def __init__(self, name, model):
Dog.__init__(self, name) # 调用Dog初始化
Robot.__init__(self) # 调用Robot初始化
self.model = model # 新增属性
def work(self): # 组合父类功能
return f"{self.speak()} 然后 {self.action()}"
# 测试继承
# 测试单继承
buddy = Dog("Buddy")
print(f"{buddy.name}叫: {buddy.speak()}") # Buddy叫: 汪汪!
print(buddy.eat()) # 吃东西(继承自Animal)
print(buddy.fetch()) # 叼回飞盘(Dog特有)
# 测试多继承
robo_dog = RoboDog("机器狗", "X-100")
print(robo_dog.name) # 机器狗(来自Animal)
print(robo_dog.speak()) # 汪汪!(来自Dog)
print(robo_dog.action()) # 执行任务(来自Robot)
print(robo_dog.work()) # 汪汪! 然后 执行任务(组合功能)
# 查看MRO顺序
print("RoboDog的MRO:", [cls.__name__ for cls in RoboDog.mro()])
# 输出: ['RoboDog', 'Dog', 'Animal', 'Robot', 'object']
2.3 多态(Polymorphism)
概念解析:
多态指不同对象对同一消息有不同响应方式,通常通过方法重写实现。"相同接口,不同实现",提高代码灵活性。
class Bird:
def fly(self):
return "飞行中"
class Penguin(Bird):
def fly(self): # 方法重写(多态实现)
return "企鹅不会飞"
class Airplane:
def fly(self): # 鸭子类型:相同方法名
return "飞机起飞"
# 测试多态
def test_fly(entity):
"""测试飞行能力(统一接口)"""
print(entity.fly())
# 测试不同对象的fly方法
test_fly(Bird()) # 飞行中
test_fly(Penguin()) # 企鹅不会飞
test_fly(Airplane()) # 飞机起飞(鸭子类型)
# 验证不同类型
print(type(Bird()), type(Penguin()), type(Airplane())) # 三个不同类
三、数据访问级别
3.1 公有(Public)
概念解析:
- 无特殊前缀标识
- 类内、类外可直接访问
- 适用于提供对外的接口方法
class Student:
def __init__(self, name):
self.name = name # 公有属性
def display(self): # 公有方法
return f"学生: {self.name}"
# 测试公有成员
stu = Student("李四")
print(stu.name) # 直接访问属性: 李四
print(stu.display()) # 调用公有方法: 学生: 李四
3.2 私有(Private)
概念解析:
- 双下划线前缀
__private_var
- 仅类内可以访问
- 防止外部直接修改重要数据
- Python实际通过名称修饰(name mangling)实现
class PrivateDemo:
def __init__(self):
self.__secret = "机密数据"
def __private_method(self):
return "私有方法调用"
def access_private(self):
# 内部访问私有成员
print("内部访问:", self.__secret)
print("内部调用:", self.__private_method())
# 测试私有成员
p = PrivateDemo()
p.access_private()
# 输出:
# 内部访问: 机密数据
# 内部调用: 私有方法调用
# 尝试外部访问私有成员
try:
print(p.__secret) # 失败
except AttributeError as e:
print("外部访问私有属性失败:", e)
try:
p.__private_method() # 失败
except AttributeError as e:
print("外部调用私有方法失败:", e)
3.3 保护(Protected)
概念解析:
- 单下划线前缀
_protected_var
- 类内和子类可访问
- 类外可访问但约定上"不要访问"
- Python没有强制保护,主要靠开发约定
class Base:
def __init__(self):
self._protected_data = "保护数据"
def _protected_method(self):
return "保护方法"
class Sub(Base):
def show(self):
print(self._protected_data) # 子类访问保护成员
print(self._protected_method())
# 测试保护成员
base = Base()
print("类外访问保护成员(不推荐):", base._protected_data) # 可访问但会警告
sub = Sub()
sub.show() # 正常输出保护数据和方法
四、类成员类型
4.1 实例成员
概念解析:
- 实例属性:每个对象独有的属性,在
__init__
中通过self.var = value
定义 - 实例方法:第一个参数为
self
,操作实例数据 - 实例数据:属于特定对象的状态数据
class Car:
"""汽车类(实例成员)"""
def __init__(self, model, year):
# 实例属性
self.model = model # 车型
self.year = year # 年份
self.mileage = 0 # 行驶里程
# 实例方法
def drive(self, km):
"""驾驶方法(操作实例数据)"""
self.mileage += km
return f"已行驶 {self.mileage} 公里"
# 测试实例成员
my_car = Car("Model S", 2022)
your_car = Car("Model 3", 2023)
print(my_car.drive(100)) # 已行驶 100 公里
print(my_car.drive(50)) # 已行驶 150 公里(相同实例)
print(your_car.drive(80)) # 已行驶 80 公里(不同实例)
4.2 类属性
概念解析:
- 在类内直接定义(不在方法内)
- 所有实例共享同一份数据
- 通过类名或实例均可访问
- 修改类属性会影响所有实例
class Galaxy:
"""星系类(类属性示例)"""
# 类属性
gravity = 9.8 # 重力加速度(m/s²)
def __init__(self, name):
self.name = name
# 测试类属性
earth = Galaxy("地球")
mars = Galaxy("火星")
print(earth.gravity) # 9.8
print(mars.gravity) # 9.8
# 修改类属性
Galaxy.gravity = 3.7
print(earth.gravity) # 3.7(所有实例均改变)
print(mars.gravity) # 3.7
4.3 类方法
概念解析:
@classmethod
装饰器标记- 第一个参数为
cls
(表示类本身) - 可访问类属性但不可访问实例属性
- 常用于替代构造方法(创建不同场景实例)
class DateUtil:
"""日期工具类(类方法)"""
@classmethod
def is_leap_year(cls, year):
"""判断是否为闰年(类方法)"""
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
@classmethod
def create_year_report(cls, year):
"""创建年度报告(使用类方法)"""
return f"{year}年: {'闰年' if cls.is_leap_year(year) else '平年'}"
# 测试类方法
# 直接通过类名调用(无需实例化)
print(DateUtil.is_leap_year(2024)) # True
print(DateUtil.create_year_report(2023)) # 2023年: 平年
# 也可通过实例调用(但不推荐)
util = DateUtil()
print(util.is_leap_year(2000)) # True
4.4 静态方法
概念解析:
@staticmethod
装饰器标记- 无特殊参数(无
self
或cls
) - 不能访问类或实例属性
- 类似普通函数,但逻辑上与类相关
class MathUtils:
"""数学工具类(静态方法)"""
@staticmethod
def add(a, b):
"""加法(静态方法)"""
return a + b
@staticmethod
def factorial(n):
"""阶乘计算(递归实现)"""
return 1 if n == 0 else n * MathUtils.factorial(n-1)
# 测试静态方法
# 直接通过类名调用
print(MathUtils.add(7, 3)) # 10
print(MathUtils.factorial(5)) # 120
# 也可通过实例调用(但不推荐)
calc = MathUtils()
print(calc.add(10, 20)) # 30
五、动态特性与魔法方法
5.1 动态属性管理
概念解析:
Python作为动态语言,允许运行时增删改类和对象的成员:
- 动态添加/删除属性
- 动态添加/删除方法
- 动态修改类结构
class Config:
"""配置类(演示动态特性)"""
pass
# 创建配置对象
config = Config()
# 动态添加属性
config.host = "localhost"
config.port = 8080
# 动态添加方法
def log_info(self, message):
return f"[{self.host}:{self.port}] {message}"
Config.log = log_info # 添加到类
config.log = lambda self, msg: f"Dynamic: {msg}" # 添加到实例
# 动态删除属性
del config.port
# 测试动态添加的属性
print(config.host) # localhost
print(config.log(config, "测试")) # Dynamic: 测试(实例方法)
print(Config.log(config, "类方法调用")) # [localhost:8080] 类方法调用
# 测试删除属性
try:
print(config.port) # 失败
except AttributeError:
print("port属性已删除")
# 测试添加新属性
config.timeout = 30
print(config.timeout) # 30
6. 动态特性与魔法方法
6.1 动态属性管理
class DynamicObj:
pass
# 动态添加属性/方法
obj = DynamicObj()
obj.new_property = "动态创建" # 添加属性
# 动态添加方法
def dynamic_method(self):
return "动态添加的方法"
DynamicObj.dynamic_method = dynamic_method
# 测试动态特性
print(obj.new_property) # "动态创建"
print(obj.dynamic_method()) # "动态添加的方法"
# 删除属性
del obj.new_property
5.2 核心魔法方法
概念解析:
Python中的"魔法方法"(双下划线方法)允许自定义类的行为:
__init__
:对象构造__str__
:用户友好字符串表示__repr__
:解释器友好字符串__getattr__
:属性不存在时调用__add__
:运算符+
重载__enter__
/__exit__
:上下文管理
class Vector:
"""向量类(魔法方法演示)"""
def __init__(self, x, y):
self.x = x
self.y = y
# 字符串表示
def __str__(self):
return f"Vector({self.x}, {self.y})"
def __repr__(self):
return f"<Vector x={self.x} y={self.y}>"
# 运算符重载
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
# 属性不存在时
def __getattr__(self, name):
return f"{name}属性不存在"
# 上下文管理
def __enter__(self):
print("进入向量上下文")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("退出向量上下文")
# 测试魔法方法
# 创建向量
v1 = Vector(2, 3)
v2 = Vector(4, 5)
# 测试字符串方法
print(str(v1)) # Vector(2, 3)
print(repr(v1)) # <Vector x=2 y=3>
# 测试运算符重载
v3 = v1 + v2
print(v3) # Vector(6, 8)
# 测试不存在的属性
print(v1.z) # z属性不存在
# 测试上下文管理
with Vector(1, 1) as v:
print(f"操作向量: {v}")
# 输出:
# 进入向量上下文
# 操作向量: Vector(1, 1)
# 退出向量上下文
六、面向过程 vs 面向对象
6.1 面向过程编程(POP)
概念解析:
- 以函数为基础单元
- 强调"步骤分解"(先做什么,再做什么)
- 数据与方法分离
- 适用于简单线性任务
# 面向过程:学生成绩计算
def calculate_average(student):
"""计算学生平均分(函数操作数据)"""
total = sum(student['scores'])
return total / len(student['scores'])
def generate_report(students):
"""生成报告(过程式)"""
print("成绩报告".center(30, '='))
for s in students:
avg = calculate_average(s)
print(f"{s['name']}: 平均分 {avg:.1f}")
# 数据结构
students = [
{"name": "张三", "scores": [85, 92, 78]},
{"name": "李四", "scores": [90, 88, 95]}
]
# 执行流程
generate_report(students)
6.2 面向对象编程(OOP)
概念解析:
- 以类和对象为基础单元
- 强调"对象职责"(谁负责做什么)
- 数据和方法封装在对象中
- 适合构建复杂系统
# 面向对象实现
class Student:
"""学生类"""
def __init__(self, name, scores):
self.name = name
self.scores = scores
def calculate_average(self):
"""计算平均分(对象方法操作对象数据)"""
total = sum(self.scores)
return total / len(self.scores)
def display_report(self):
"""显示报告(对象职责)"""
avg = self.calculate_average()
return f"{self.name}: 平均分 {avg:.1f}"
class ReportSystem:
"""报告系统"""
def generate_reports(self, students):
print("成绩报告".center(30, '='))
for student in students:
print(student.display_report())
# 使用对象
students = [
Student("张三", [85, 92, 78]),
Student("李四", [90, 88, 95])
]
ReportSystem().generate_reports(students)
6.3 范式对比总结
特性 | 面向过程(POP) | 面向对象(OOP) |
---|---|---|
核心单元 | 函数 | 对象(类) |
数据管理 | 数据与方法分离 | 数据与方法封装 |
代码组织 | 按执行流程组织 | 按对象职责组织 |
复用机制 | 函数调用 | 继承/组合 |
设计重点 | "怎么做"(步骤分解) | "谁来做"(对象职责) |
适用场景 | 简单脚本/数据处理 | GUI/游戏/企业应用 |
选用建议:
- 简单任务:文件处理、数据清洗等使用面向过程
- 中等复杂度:混合使用(主流程过程式+复杂部分对象封装)
- 大型系统:完全面向对象设计
- 特定领域:游戏开发(OOP为主)、科学计算(过程式为主)
# 混合范式示例:电商订单处理
class Product:
"""商品对象(OOP)"""
def __init__(self, name, price):
self.name = name
self.price = price
# 面向过程函数
def calculate_total(products):
"""计算总价(过程式函数)"""
return sum(p.price for p in products)
# 主流程
if __name__ == "__main__":
# 创建对象
cart = [
Product("iPad", 3000),
Product("AirPods", 1200)
]
# 过程式计算
total = calculate_total(cart)
print(f"订单总额: ¥{total}")
七、综合实战:图书馆系统
class Book:
"""书籍类(面向对象)"""
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn
self.available = True
def check_out(self):
"""借出书籍"""
if self.available:
self.available = False
return True
return False
def return_book(self):
"""归还书籍"""
self.available = True
def __str__(self):
return f"《{self.title}》- {self.author} [{'可借' if self.available else '已借'}]"
# 面向过程管理函数
def add_book(library, title, author, isbn):
"""添加新书(过程式函数)"""
new_book = Book(title, author, isbn)
library[isbn] = new_book
return f"添加成功: 《{title}》"
def borrow_book(library, isbn):
"""借书过程(过程式函数操作对象)"""
if isbn not in library:
return "查无此书"
book = library[isbn]
if book.check_out():
return f"成功借阅: 《{book.title}》"
return "该书已被借出"
# 主程序
def main():
library = {}
# 添加书籍
print(add_book(library, "Python编程", "Eric Matthes", "9787115428028"))
print(add_book(library, "深入理解计算机系统", "Randal Bryant", "9787111544937"))
# 借阅书籍
print(borrow_book(library, "9787111544937")) # 成功借阅
print(borrow_book(library, "9787111544937")) # 已借出
# 显示状态
for isbn, book in library.items():
print(book)
if __name__ == "__main__":
main()
输出示例:
添加成功: 《Python编程》
添加成功: 《深入理解计算机系统》
成功借阅: 《深入理解计算机系统》
该书已被借出
《Python编程》- Eric Matthes [可借]
《深入理解计算机系统》- Randal Bryant [已借]
总结与实践建议
核心概念回顾:
- 类与对象:类是蓝图,对象是实例
- 封装:通过访问控制保护内部状态
- 继承:子类复用父类功能(单继承/多继承)
- 多态:同一接口不同实现
- 成员类型:实例属性/方法 vs 类属性/方法 vs 静态方法
- 动态特性:运行时修改类结构的能力
- 魔法方法:定制类行为的特殊方法
最佳实践:
- 简单任务使用面向过程
- 复杂系统使用面向对象
- 私有属性使用双下划线(
__private
) - 保护属性使用单下划线(
_protected
) - 类方法使用
@classmethod
- 工具方法使用
@staticmethod
- 运算符重载使用相应魔法方法
- 避免滥用多继承
# 最终代码:完整图书管理系统(OOP版本)
class LibrarySystem:
"""图书馆系统(完整OOP实现)"""
def __init__(self):
self.books = {}
def add_book(self, title, author, isbn):
book = Book(title, author, isbn)
self.books[isbn] = book
return f"添加成功: 《{title}》"
def borrow_book(self, isbn):
if isbn not in self.books:
return "查无此书"
if self.books[isbn].check_out():
return f"借阅成功: 《{self.books[isbn].title}》"
return "该书已被借出"
def display_books(self):
print("馆藏图书".center(40, '='))
for book in self.books.values():
print(book)
print("=" * 40)
# 使用示例
if __name__ == "__main__":
library = LibrarySystem()
library.add_book("Python编程", "Eric Matthes", "9787115428028")
library.add_book("流畅的Python", "Luciano Ramalho", "9787115475898")
library.borrow_book("9787115475898")
library.display_books()
运行输出:
====================馆藏图书====================
《Python编程》- Eric Matthes [可借]
《流畅的Python》- Luciano Ramalho [已借]
========================================