Python程序设计强基计划10讲 · 第六讲:面向对象编程(OOP)入门——封装、继承与多态
Python程序设计强基计划10讲 · 第六讲面向对象编程OOP入门——封装、继承与多态作者培风图南以星河揽胜发布时间2026年3月31日适用对象已掌握函数、模块、异常处理等基础的Python学习者前置知识第五讲《文件操作与异常处理——稳健编程的基石》标签Python OOP、类与对象、封装、继承、多态、CSDN博客引言从“怎么做”到“谁来做”的思维跃迁在前五讲中我们学会了如何用函数组织逻辑、用模块管理代码、用异常保障稳健。但随着项目规模扩大你可能会发现数据与操作分散在各处难以维护相似功能重复实现违反 DRY 原则代码耦合度高修改一处牵动全局。面向对象编程Object-Oriented Programming, OOP正是解决这些问题的范式。它将数据属性与行为方法封装在对象中通过继承复用代码利用多态实现灵活扩展。本讲将带你系统掌握OOP三大核心支柱封装Encapsulation隐藏内部细节暴露安全接口继承Inheritance构建类层次实现代码复用多态Polymorphism同一接口多种实现。掌握这些你将完成从“过程式思维”关注步骤到“对象式思维”关注实体的质变一、类与对象OOP 的基本单元1.1 什么是类什么是对象类Class对象的“蓝图”或“模板”定义了属性和方法对象Object类的“实例”拥有具体的数据和行为。 类比理解现实世界编程世界汽车设计图Car类一辆具体的特斯拉Car类的一个对象1.2 定义类与创建对象classDog:狗类def__init__(self,name,age):初始化方法构造器self.namename# 实例属性self.ageagedefbark(self):叫的方法print(f{self.name}says: Woof!)# 创建对象实例化my_dogDog(Buddy,3)your_dogDog(Lucy,5)# 调用方法my_dog.bark()# Buddy says: Woof!✅ 关键概念解析__init__构造方法创建对象时自动调用self代表当前实例必须作为第一个参数但调用时无需传入self.name实例属性每个对象独立拥有。注意Python 中所有方法默认都是公有public无严格私有概念。1.3 类属性 vs 实例属性类型定义位置共享范围访问方式类属性类内部方法外部所有实例共享ClassName.attr或instance.attr实例属性__init__或其他方法中每个实例独立self.attr 示例classDog:speciesCanis familiaris# 类属性def__init__(self,name):self.namename# 实例属性dog1Dog(Buddy)dog2Dog(Lucy)print(dog1.species)# Canis familiarisprint(dog2.species)# Canis familiarisDog.speciesNew Species# 修改类属性print(dog1.species)# New Species所有实例受影响用途类属性常用于常量或计数器。二、封装隐藏细节暴露接口2.1 为什么需要封装降低复杂度用户只需知道“做什么”无需关心“怎么做”提高安全性防止外部直接修改内部状态增强可维护性内部实现可自由变更不影响外部调用。2.2 Python 的“私有”约定Python没有真正的私有成员但通过命名约定实现封装命名含义外部访问建议public公有属性/方法自由访问_protected受保护单下划线“请勿直接访问”__private私有双下划线名称改写Name Mangling极难访问 封装示例银行账户classBankAccount:def__init__(self,initial_balance0):self._balanceinitial_balance# 受保护属性defdeposit(self,amount):ifamount0:self._balanceamountelse:raiseValueError(Deposit amount must be positive)defwithdraw(self,amount):if0amountself._balance:self._balance-amountelse:raiseValueError(Invalid withdrawal amount)defget_balance(self):returnself._balance# 安全的访问接口# 使用accountBankAccount(100)account.deposit(50)print(account.get_balance())# 150# account._balance -999 # 不推荐破坏封装原则通过方法操作属性而非直接访问。2.3 属性Property更优雅的封装使用property装饰器将方法变为“属性式”访问。✅ 改进银行账户classBankAccount:def__init__(self,initial_balance0):self._balanceinitial_balancepropertydefbalance(self):只读余额returnself._balancedefdeposit(self,amount):ifamount0:self._balanceamountelse:raiseValueError(Deposit amount must be positive)# 使用accountBankAccount(100)print(account.balance)# 像访问属性一样调用方法# account.balance 200 # AttributeError! 无 setter✅ 可写的属性classTemperature:def__init__(self,celsius0):self._celsiuscelsiuspropertydefcelsius(self):returnself._celsiuscelsius.setterdefcelsius(self,value):ifvalue-273.15:raiseValueError(Temperature below absolute zero!)self._celsiusvalue tempTemperature()temp.celsius25# 调用 setterprint(temp.celsius)# 25优势保持简洁语法同时加入验证逻辑。三、继承代码复用的强大机制3.1 什么是继承子类Child Class继承父类Parent Class的属性和方法子类可扩展或重写父类行为实现“is-a”关系如Dogis aAnimal。3.2 基本继承语法classAnimal:def__init__(self,name):self.namenamedefspeak(self):raiseNotImplementedError(Subclass must implement this method)classDog(Animal):# Dog 继承 Animaldefspeak(self):returnf{self.name}says: Woof!classCat(Animal):defspeak(self):returnf{self.name}says: Meow!# 使用animals[Dog(Buddy),Cat(Whiskers)]foranimalinanimals:print(animal.speak())# Buddy says: Woof!# Whiskers says: Meow!✅ 关键点class Child(Parent):表示继承super()调用父类方法见下文父类方法可被子类重写Override。3.3 super()调用父类方法当子类需要扩展父类行为时用super()避免重复代码。 示例带品种的狗classDog(Animal):def__init__(self,name,breed):super().__init__(name)# 调用父类 __init__self.breedbreed# 子类特有属性defspeak(self):returnsuper().speak() (barks loudly)# 扩展父类方法dogDog(Buddy,Golden Retriever)print(dog.speak())# Buddy says: Woof! (barks loudly)优势解耦子类与父类的具体实现提高可维护性。3.4 多重继承与方法解析顺序MROPython 支持多重继承但需谨慎使用。 多重继承示例classFlyer:deffly(self):returnFlying high!classSwimmer:defswim(self):returnSwimming fast!classDuck(Animal,Flyer,Swimmer):defspeak(self):returnf{self.name}says: Quack!duckDuck(Donald)print(duck.fly())# Flying high!print(duck.swim())# Swimming fast!⚠️ 方法解析顺序MROPython 使用C3 线性化算法确定方法调用顺序通过ClassName.__mro__查看print(Duck.__mro__)# (class __main__.Duck, class __main__.Animal,# class __main__.Flyer, class __main__.Swimmer, class object)建议优先使用组合Composition而非多重继承避免复杂性。四、多态接口统一的灵活性4.1 什么是多态同一接口多种实现调用者无需关心对象的具体类型提高代码的可扩展性和可维护性。 多态示例图形面积计算fromabcimportABC,abstractmethodclassShape(ABC):# 抽象基类abstractmethoddefarea(self):passclassRectangle(Shape):def__init__(self,width,height):self.widthwidth self.heightheightdefarea(self):returnself.width*self.heightclassCircle(Shape):def__init__(self,radius):self.radiusradiusdefarea(self):return3.14159*self.radius**2# 多态使用shapes[Rectangle(3,4),Circle(2)]forshapeinshapes:print(fArea:{shape.area():.2f})# Area: 12.00# Area: 12.57✅ 关键点Shape是抽象基类ABC不能实例化abstractmethod强制子类实现area方法循环中调用shape.area()时自动调用对应子类的实现。优势新增图形如 Triangle无需修改循环代码4.2 鸭子类型Duck TypingPython 的多态哲学Python 更推崇“鸭子类型”“如果它走起来像鸭子叫起来像鸭子那它就是鸭子。”即不检查类型只检查方法是否存在。 鸭子类型示例defmake_sound(animal):# 不关心 animal 是什么类型只要有 speak() 方法就行print(animal.speak())make_sound(Dog(Buddy))# Buddy says: Woof!make_sound(Cat(Lucy))# Lucy says: Meow!# 甚至可以是非 Animal 类classRobot:defspeak(self):returnBeep boop!make_sound(Robot())# Beep boop! 无需继承 AnimalPython 之道“Easier to Ask for Forgiveness than Permission (EAFP)”与其检查类型不如直接调用并处理异常。五、典型误区与避坑指南误区1滥用继承问题为复用少量代码而继承导致类层次臃肿修正优先考虑组合“has-a”关系classCar:def__init__(self):self.engineEngine()# 组合classEngine:defstart(self):returnEngine started误区2忽略super()的正确用法问题在多重继承中手动调用父类方法破坏 MRO修正始终用super()。误区3过度封装问题所有属性都设为私有提供大量 getter/setter修正Python 遵循“We’re all consenting adults here”原则先公开仅在需要验证/计算时转为property。误区4混淆类方法与静态方法类型装饰器第一个参数用途实例方法无self操作实例数据类方法classmethodcls操作类数据、替代构造器静态方法staticmethod无工具函数与类/实例无关classPerson:speciesHomo sapiensclassmethoddefget_species(cls):returncls.speciesstaticmethoddefis_adult(age):returnage18六、动手练习巩固OOP核心概念练习1封装实践创建Student类包含私有属性_score0-100set_score()方法带验证get_grade()方法返回 A/B/C/D/F。练习2继承与多态创建Vehicle抽象基类子类Car和Bicycle实现start_engine()自行车应抛出NotImplementedError。练习3属性装饰器创建Rectangle类用property实现area和perimeter只读属性。七、本讲小结OOP 的三大境界会用定义类、创建对象、使用继承懂理理解封装意义、MRO 规则、多态本质善用合理选择继承/组合写出高内聚低耦合的代码。关键口诀“封装藏细节继承复代码多态提扩展。”“优先组合非继承鸭子类型更Pythonic。”“属性装饰器验证又简洁。”下期预告第七讲《标准库精要——高效开发的秘密武器》下一讲将深入解析 Python 标准库的精华模块os/pathlib文件系统操作datetime日期时间处理json/csv数据序列化collections高级数据结构助你告别重复造轮子提升开发效率原创声明本文为《Python程序设计强基计划10讲》系列第六讲版权归作者所有。互动邀请你在学习OOP时遇到过哪些困惑欢迎评论区交流关注我系统掌握Python核心编程范式为大型项目开发奠基