13-面向对象
Python面向对象编程全面指南
一、面向对象编程概述
1.1 面向对象的基本概念
1.1.1 为什么需要面向对象
在程序开发中,我们需要一种有效的方式来组织和管理数据。面向对象编程(OOP)提供了一种更加结构化和可维护的代码组织方式。
传统变量方式的局限性:
# 混乱的数据组织方式
student_1 = "我叫周杰轮,今年31岁,男的,来自中国台湾省"
student_2 = "我叫林军杰,今年33岁,男的,来自中国山东省"
# 问题:数据分散,难以统一管理和操作
1.1.2 面向对象的优势
面向对象编程通过类和对象来组织数据,类似于生活中的表格登记:
1.2 面向对象三大特性
- 封装:将数据和行为包装在类中
- 继承:实现代码复用和扩展
- 多态:同一操作作用于不同对象产生不同行为
二、类与对象基础
2.1 类的定义与使用
2.1.1 类的基本语法
class 类名称:
# 类的属性(成员变量)
属性1 = None
属性2 = None
# 类的行为(成员方法)
def 方法名(self, 参数列表):
方法体
2.1.2 实际示例
class Student:
# 类的属性
name = None # 学生姓名
age = None # 学生年龄
gender = None # 学生性别
address = None # 学生地址
# 类的行为
def say_hi(self):
print(f"大家好,我是{self.name},今年{self.age}岁")
def study(self, course):
print(f"{self.name}正在学习{course}课程")
2.1.3 创建和使用对象
# 创建对象(生产表格)
student1 = Student()
student2 = Student()
# 对象属性赋值(填写表格)
student1.name = "周杰轮"
student1.age = 31
student1.gender = "男"
student1.address = "台湾省"
student2.name = "林军杰"
student2.age = 33
student2.gender = "男"
student2.address = "山东省"
# 使用对象方法
student1.say_hi() # 输出:大家好,我是周杰轮,今年31岁
student2.study("Python") # 输出:林军杰正在学习Python课程
2.2 self关键字详解
2.2.1 self的作用
self表示类对象自身,用于在方法内部访问类的属性和其他方法。
class Student:
name = None
age = None
def introduce(self):
# 使用self访问对象的属性
print(f"姓名:{self.name},年龄:{self.age}")
def set_info(self, name, age):
# 使用self设置对象的属性
self.name = name
self.age = age
self.introduce() # 调用其他方法也需要self
2.2.2 方法调用机制
student = Student()
student.set_info("王小明", 20)
# 等价于:Student.set_info(student, "王小明", 20)
# Python自动将student作为第一个参数self传入
三、构造方法
3.1 构造方法的概念
3.1.1 为什么需要构造方法
传统的属性赋值方式繁琐:
student = Student()
student.name = "张三"
student.age = 20
student.gender = "男"
# 需要多行代码完成初始化
使用构造方法可以简化初始化过程。
3.1.2 构造方法语法
class Student:
def __init__(self, name, age, gender):
"""构造方法,在创建对象时自动执行"""
self.name = name
self.age = age
self.gender = gender
print("学生对象创建完成!")
def introduce(self):
print(f"我叫{self.name},今年{self.age}岁")
# 使用构造方法初始化
student = Student("李四", 22, "女")
student.introduce() # 输出:我叫李四,今年22岁
3.2 构造方法实践
3.2.1 学生信息录入系统
class Student:
def __init__(self, name, age, address):
"""构造方法初始化学生信息"""
self.name = name
self.age = age
self.address = address
def display_info(self):
"""显示学生信息"""
print(f"学生信息:姓名:{self.name}, 年龄:{self.age}, 地址:{self.address}")
# 批量录入学生信息
students = []
for i in range(3):
print(f"录入第{i+1}个学生信息:")
name = input("姓名:")
age = int(input("年龄:"))
address = input("地址:")
student = Student(name, age, address)
students.append(student)
student.display_info()
四、类的内置方法
4.1 常用魔术方法
4.1.1 __str__ 方法
控制对象转换为字符串的表现形式:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""定义对象字符串表示"""
return f"Student对象:name={self.name}, age={self.age}"
student = Student("周杰轮", 31)
print(student) # 输出:Student对象:name=周杰轮, age=31
print(str(student)) # 输出:Student对象:name=周杰轮, age=31
4.1.2 __lt__ 方法
实现对象的小于比较:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
"""定义小于比较规则"""
return self.age < other.age
stu1 = Student("张三", 20)
stu2 = Student("李四", 22)
print(stu1 < stu2) # 输出:True
print(stu1 > stu2) # 输出:False(自动支持)
4.1.3 __le__ 方法
实现对象的小于等于比较:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __le__(self, other):
"""定义小于等于比较规则"""
return self.score <= other.score
stu1 = Student("张三", 85)
stu2 = Student("李四", 85)
print(stu1 <= stu2) # 输出:True
print(stu1 >= stu2) # 输出:True(自动支持)
4.1.4 __eq__ 方法
实现对象的相等比较:
class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
def __eq__(self, other):
"""定义相等比较规则"""
return self.student_id == other.student_id
stu1 = Student("张三", "2023001")
stu2 = Student("李四", "2023001")
stu3 = Student("王五", "2023002")
print(stu1 == stu2) # 输出:True
print(stu1 == stu3) # 输出:False
4.2 魔术方法综合应用
class Product:
"""商品类"""
def __init__(self, name, price, quantity):
self.name = name
self.price = price
self.quantity = quantity
def __str__(self):
return f"商品:{self.name},价格:{self.price}元,库存:{self.quantity}"
def __lt__(self, other):
return self.price < other.price
def __eq__(self, other):
return self.name == other.name and self.price == other.price
# 使用示例
p1 = Product("手机", 2999, 10)
p2 = Product("平板", 3999, 5)
p3 = Product("手机", 2999, 8)
print(p1) # 输出商品信息
print(p1 < p2) # 输出:True
print(p1 == p3) # 输出:True
五、封装
5.1 封装的概念
5.1.1 什么是封装
封装是将现实世界事物的属性和行为封装到类中,描述为成员变量和成员方法。
5.1.2 私有成员
私有成员是对外部隐藏的属性和方法,只能在类内部访问:
class Phone:
# 公开成员变量
IMEI = None # 序列号
producer = None # 厂商
# 私有成员变量
__current_voltage = None # 当前电压
def call_by_5g(self):
"""公开方法"""
if self.__check_5g():
print("5G通话已开启")
else:
print("5G通话关闭,使用4G通话")
def __check_5g(self):
"""私有方法:检查5G状态"""
if self.__current_voltage >= 1:
return True
else:
return False
5.2 封装实践
5.2.1 手机类设计
class Phone:
def __init__(self):
# 私有成员变量
self.__is_5g_enable = True # 5G状态
def __check_5g(self):
"""私有方法:检查5G状态"""
if self.__is_5g_enable:
print("5G开启")
else:
print("5G关闭,使用4G网络")
def call_by_5g(self):
"""公开方法:5G通话"""
self.__check_5g()
print("正在通话中")
# 使用
phone = Phone()
phone.call_by_5g()
# 输出:
# 5G开启
# 正在通话中
# 以下操作会报错
# phone.__is_5g_enable = False # 错误:无法直接访问私有变量
# phone.__check_5g() # 错误:无法直接调用私有方法
5.2.2 封装的优点
- 数据保护:防止外部直接修改内部数据
- 接口统一:提供统一的访问接口
- 实现隐藏:隐藏内部实现细节,降低耦合度
六、继承
6.1 继承的基本概念
6.1.1 为什么需要继承
继承可以实现代码复用,避免重复编写相似的代码。
6.1.2 单继承
class Phone:
"""父类:手机基类"""
IMEI = None # 序列号
producer = None # 厂商
def call_by_4g(self):
print("4G通话")
class Phone2022(Phone):
"""子类:2022年手机"""
face_id = True # 面部识别
def call_by_5g(self):
print("2022最新5G通话")
# 使用
phone2022 = Phone2022()
phone2022.call_by_4g() # 继承自父类
phone2022.call_by_5g() # 自己的功能
6.2 多继承
6.2.1 多继承语法
class NFCReader:
"""NFC读取器"""
nfc_type = "第五代"
producer = "HM"
def read_card(self):
print("读取NFC卡")
class RemoteControl:
"""遥控器"""
rc_type = "红外遥控"
def control(self):
print("红外遥控开启")
class MyPhone(Phone, NFCReader, RemoteControl):
"""多继承:我的手机"""
pass
# 使用
my_phone = MyPhone()
my_phone.call_by_4g() # 来自Phone
my_phone.read_card() # 来自NFCReader
my_phone.control() # 来自RemoteControl
6.2.2 多继承注意事项
class A:
value = "A"
class B:
value = "B"
class C(A, B): # 继承顺序:A → B
pass
class D(B, A): # 继承顺序:B → A
pass
print(C().value) # 输出:"A"(优先使用A的value)
print(D().value) # 输出:"B"(优先使用B的value)
6.3 方法重写
6.3.1 重写父类方法
class Animal:
def speak(self):
print("动物发出声音")
class Dog(Animal):
def speak(self):
print("汪汪汪") # 重写父类方法
class Cat(Animal):
def speak(self):
print("喵喵喵") # 重写父类方法
# 使用
dog = Dog()
cat = Cat()
dog.speak() # 输出:汪汪汪
cat.speak() # 输出:喵喵喵
6.3.2 调用父类方法
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
# 方式1:使用父类名调用
Animal.__init__(self, name)
# 方式2:使用super()调用(推荐)
super().__init__(name)
self.breed = breed
dog = Dog("旺财", "金毛")
七、类型注解
7.1 变量类型注解
7.1.1 基础类型注解
# 基础数据类型注解
var_1: int = 10
var_2: float = 3.14
var_3: bool = True
var_4: str = "hello"
# 类对象类型注解
class Student:
pass
stu: Student = Student()
7.1.2 容器类型注解
from typing import List, Dict, Tuple, Set
# 基础容器注解
my_list: List[int] = [1, 2, 3]
my_dict: Dict[str, int] = {"age": 20, "score": 95}
my_tuple: Tuple[str, int, bool] = ("张三", 20, True)
my_set: Set[int] = {1, 2, 3}
# 注释中的类型注解
data = get_data() # type: Dict[str, int]
7.2 函数类型注解
7.2.1 函数参数和返回值注解
def add(x: int, y: int) -> int:
"""加法函数"""
return x + y
def process_students(students: List[Student]) -> Dict[str, int]:
"""处理学生列表,返回姓名-年龄字典"""
return {s.name: s.age for s in students}
# 使用
result: int = add(5, 3)
print(result) # 输出:8
7.2.2 Union类型注解
from typing import Union
def process_data(data: Union[int, str, List]) -> Union[int, str]:
"""处理多种类型数据"""
if isinstance(data, int):
return data * 2
elif isinstance(data, str):
return data.upper()
else:
return str(len(data))
# 容器中的Union类型
mixed_list: List[Union[int, str]] = [1, "hello", 2, "world"]
八、多态
8.1 多态的概念
8.1.1 什么是多态
多态指的是同一操作作用于不同对象,可以产生不同的执行结果。
class Animal:
def speak(self):
pass # 抽象方法
class Dog(Animal):
def speak(self):
print("汪汪汪")
class Cat(Animal):
def speak(self):
print("喵喵喵")
def make_sound(animal: Animal):
"""同一函数,不同表现"""
animal.speak()
# 使用多态
dog = Dog()
cat = Cat()
make_sound(dog) # 输出:汪汪汪
make_sound(cat) # 输出:喵喵喵
8.2 抽象类与接口
8.2.1 抽象类设计
class AC:
"""空调抽象类(接口)"""
def cool_wind(self):
"""制冷(抽象方法)"""
pass
def hot_wind(self):
"""制热(抽象方法)"""
pass
def swing_l_r(self):
"""左右摆风(抽象方法)"""
pass
class MideaAC(AC):
"""美的空调实现"""
def cool_wind(self):
print("美的空调核心制冷科技")
def hot_wind(self):
print("美的空调电热丝加热")
def swing_l_r(self):
print("美的空调无风感左右摆风")
class GreeAC(AC):
"""格力空调实现"""
def cool_wind(self):
print("格力空调变频省电制冷")
def hot_wind(self):
print("格力空调电热丝加热")
def swing_l_r(self):
print("格力空调静音左右摆风")
8.2.2 多态的应用
def use_ac(ac: AC):
"""使用空调(多态应用)"""
ac.cool_wind()
ac.swing_l_r()
# 使用不同的空调实现
midea = MideaAC()
gree = GreeAC()
use_ac(midea) # 使用美的空调
use_ac(gree) # 使用格力空调
九、综合案例实战
9.1 银行ATM系统面向对象设计
9.1.1 类设计
class Account:
"""账户类"""
def __init__(self, account_id: str, name: str, balance: float = 0.0):
self.__account_id = account_id # 私有属性:账户ID
self.name = name # 公开属性:姓名
self.__balance = balance # 私有属性:余额
def get_balance(self) -> float:
"""获取余额"""
return self.__balance
def deposit(self, amount: float) -> bool:
"""存款"""
if amount > 0:
self.__balance += amount
return True
return False
def withdraw(self, amount: float) -> bool:
"""取款"""
if 0 < amount <= self.__balance:
self.__balance -= amount
return True
return False
class ATM:
"""ATM机类"""
def __init__(self):
self.accounts: Dict[str, Account] = {}
self.current_account: Optional[Account] = None
def register_account(self, account_id: str, name: str) -> bool:
"""注册账户"""
if account_id not in self.accounts:
self.accounts[account_id] = Account(account_id, name)
return True
return False
def login(self, account_id: str) -> bool:
"""登录账户"""
if account_id in self.accounts:
self.current_account = self.accounts[account_id]
return True
return False
def operate(self):
"""主操作流程"""
while True:
print("\n=== ATM系统 ===")
if self.current_account:
print(f"当前用户:{self.current_account.name}")
print("1. 查询余额 2. 存款 3. 取款 4. 退出登录")
else:
print("1. 注册 2. 登录 3. 退出")
choice = input("请选择操作:")
if not self.current_account:
if choice == "1":
self._register()
elif choice == "2":
self._login()
elif choice == "3":
break
else:
if choice == "1":
self._check_balance()
elif choice == "2":
self._deposit()
elif choice == "3":
self._withdraw()
elif choice == "4":
self.current_account = None
9.2 数据分析案例
9.2.1 数据读取类
import json
from typing import List, Dict, Union
class DataReader:
"""数据读取基类"""
def __init__(self, file_path: str):
self.file_path = file_path
self.data: List[Dict] = []
def read_data(self) -> bool:
"""读取数据(抽象方法)"""
pass
def process_data(self) -> List[Dict]:
"""处理数据"""
return self.data
class JsonDataReader(DataReader):
"""JSON数据读取器"""
def read_data(self) -> bool:
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
raw_data = f.read()
self.data = json.loads(raw_data)
return True
except Exception as e:
print(f"读取JSON数据失败:{e}")
return False
class CsvDataReader(DataReader):
"""CSV数据读取器"""
def read_data(self) -> bool:
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
headers = f.readline().strip().split(',')
for line in f:
values = line.strip().split(',')
item = dict(zip(headers, values))
self.data.append(item)
return True
except Exception as e:
print(f"读取CSV数据失败:{e}")
return False
class DataAnalyzer:
"""数据分析器"""
def __init__(self, reader: DataReader):
self.reader = reader
self.analysis_result: Dict = {}
def analyze(self) -> Dict:
"""执行分析"""
if self.reader.read_data():
data = self.reader.process_data()
self.analysis_result = self._perform_analysis(data)
return self.analysis_result
return {}
def _perform_analysis(self, data: List[Dict]) -> Dict:
"""实际分析逻辑"""
# 实现具体的分析逻辑
return {"total": len(data), "analysis": "完成"}
十、面向对象最佳实践
10.1 设计原则
10.1.1 SOLID原则
- 单一职责原则:一个类只负责一个功能领域
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类可以替换父类
- 接口隔离原则:使用多个专门的接口
- 依赖倒置原则:依赖抽象而不是具体实现
10.2 代码组织建议
10.2.1 模块化组织
project/
├── models/ # 数据模型类
│ ├── __init__.py
│ ├── user.py # 用户类
│ └── product.py # 商品类
├── services/ # 业务逻辑类
│ ├── __init__.py
│ └── user_service.py
├── utils/ # 工具类
│ ├── __init__.py
│ └── file_util.py
└── main.py # 主程序
10.2.2 文档字符串规范
class Student:
"""学生类
用于管理学生的基本信息和学习行为
"""
def __init__(self, name: str, age: int):
"""初始化学生对象
Args:
name: 学生姓名
age: 学生年龄
"""
self.name = name
self.age = age
def study(self, course: str) -> str:
"""学习课程
Args:
course: 课程名称
Returns:
学习结果描述
"""
return f"{self.name}正在学习{course}"
通过系统学习面向对象编程,您已经掌握了现代编程的核心范式。面向对象编程能够帮助您编写出更加结构化、可维护和可扩展的代码。在实际项目中灵活运用这些概念,将大幅提升您的编程能力和代码质量。

浙公网安备 33010602011771号