Python进阶系列之-面向对象编程
Python进阶之面向对象编程
面向对象编程(Object-Oriented Programming,简称OOP) 是Python进阶的核心知识点,也是从“会写代码”到“会设计代码”的关键一步。相比面向过程的分步实现思路,面向对象以“对象”为核心组织代码,更贴合现实世界的认知逻辑,能大幅提升代码的复用性、扩展性与可维护性。
本文基于经典Python教程体系,系统拆解面向对象的全部核心内容,分为基础入门与高级特性两大部分,涵盖类与对象、self关键字、魔法方法、封装、继承、多态三大特性,以及类属性、类方法、静态方法等进阶知识点。全文配套可运行代码示例与图解说明,适合已掌握Python基础语法的读者系统学习,也可作为日常开发的知识点速查手册。
文章目录
第一部分:Python面向对象基础
1 什么是面向对象
学习目标
- 了解常见的编程思想分类
- 理解面向对象的核心概念
- 掌握面向对象的三大特性
1.1 两种主流编程思想
编程思想是解决问题的底层思维方式,与编程语言无关,主流分为两类:
- 面向过程:以“步骤”为核心,将问题拆解为依次执行的函数/步骤,按流程逐步实现。适合逻辑简单的线性场景,但扩展性较弱,需求变动时修改成本高。
- 面向对象:以“对象”为核心,将问题中的实体抽象为类,通过对象之间的交互完成需求。代码结构更灵活,扩展性、复用性更强,适合中大型项目开发。
Python同时支持两种编程范式,日常开发中通常是二者结合使用。
1.2 面向过程 vs 面向对象
1.2.1 面向过程思想
面向过程的核心是「步骤」:把解决问题的流程拆解成一个个依次执行的步骤,按照步骤编写代码逐一实现,是一种过程化的叙事思维。
生活案例:ATM取钱(面向过程视角)
1.2.2 面向对象思想
面向对象的核心是「对象」:不再关注执行步骤,而是将问题中的实体抽象为对象,通过对象之间的交互完成需求。
面向对象的核心理念:一切皆对象。现实世界中的冰箱、手机、汽车,乃至抽象的账户、订单,都可以被抽象为“对象”——每个对象有自己的特征(属性)和行为(方法)。
面向对象思想的优势:
- 更贴近人类的认知习惯,代码可读性更强
- 封装、继承、多态三大特性大幅提升代码复用性与扩展性
- 便于模块化管理,降低大型项目的维护成本
经典案例:把大象放进冰箱
举个经典的例子:“把大象放进冰箱”。
- 面向过程思路:打开冰箱门 → 把大象放进去 → 关上冰箱门
- 面向对象思路:抽象出「冰箱」和「大象」两个类,冰箱有开门、关门的方法,大象有移动的方法,通过对象调用方法完成需求


1.3 面向对象的三大特性
面向对象编程有三大支柱特性,也是OOP的核心价值所在:
- 封装:隐藏对象的内部实现细节,仅对外暴露有限的访问接口,控制数据的读写权限,保障数据安全,简化调用逻辑。
- 继承:子类可以复用父类的属性和方法,无需重复编写相同代码,实现代码复用,构建类的层级体系。
- 多态:同一接口在不同场景下表现出不同的行为,实现框架与实现的解耦,提升代码的扩展性。
💡 通俗理解
- 封装:我包里有什么东西、怎么放的,你不用知道,我给你什么你拿什么
- 继承:孩子继承父母的财产和天赋,还能有自己的新能力
- 多态:同一个“播放”按钮,点视频出画面,点音乐出声音
1.3.1 封装
封装的核心是「隐藏细节,暴露接口」:将对象的属性和实现细节隐藏起来,仅对外公开有限的访问接口,控制属性的读写权限。
封装的目的是增强代码安全性、简化调用逻辑,使用者无需了解内部实现,只需通过公开接口即可操作对象。
生活案例:小明的信息权限
不同身份的人能获取小明的信息范围不同,这就是现实中的封装:
| 身份 | 可获取的信息 |
|---|---|
| 银行柜员 | 身份证号、联系方式、银行卡号等 |
| 同事 | 姓名、职位、性别、年龄等 |
| 父母 | 血型、身份证号、情感状态等 |
在代码中,封装就是将数据与操作数据的方法整合为「类」,数据和函数都是类的成员。
1.3.2 继承
继承描述类与类之间的从属关系,对应现实中的「子承父业」:子类可以继承父类的属性和方法,无需重复编写相同代码。
所有继承关系都满足 is-a 原则,即「子类是父类」。

1.3.3 多态
多态指「同一消息,不同对象响应不同」:同一个方法调用,根据传入对象的不同,会执行不同的逻辑,呈现出多种状态。
生活案例:F12功能键
同一个F12按键,在不同软件中功能完全不同:
| 场景 | 功能 |
|---|---|
| WPS办公软件 | 提示用户保存文件 |
| Chrome浏览器 | 打开开发者工具 |
1.4 本节核心总结
- 编程思想是编写代码的思维方式,分为面向过程、面向对象两类
- 面向过程:以步骤为核心,逐行实现逻辑,扩展性较差
- 面向对象:以对象为核心,通过类抽象现实事物,扩展性更强
- 三大核心特性:
- 封装:将属性与方法封装在类中,对外仅暴露访问接口
- 继承:子类继承父类的属性与方法,实现代码复用
- 多态:同一函数/方法在不同场景下有不同表现
2 类与对象:OOP的基础单元
学习目标
- 理解类与对象的概念与关系
- 掌握
class关键字定义类的语法 - 掌握对象实例化与方法调用的写法
- 理解
self关键字的作用
2.1 什么是类,什么是对象
类和对象是面向对象的两个核心概念:
- 类(Class):对一类事物的抽象描述,是创建对象的“模板/图纸”,定义了这类事物共有的属性和方法。
- 对象(Object):类的具体实例,是真实存在的个体,具备类定义的全部特征与行为。
简单类比:类是汽车设计图纸,对象是按照图纸生产出来的真实汽车。一张图纸可以生产无数台汽车,一个类也可以创建无数个对象。

2.2 类的定义
Python使用class关键字定义类,基础语法如下:
class 类名:
# 类的属性与方法
方法列表
命名规范:类名推荐使用大驼峰命名法,每个单词首字母大写,如
Car、StudentInfo
示例:定义一个汽车类
# 定义汽车类
class Car:
# 定义“跑起来”的方法
def run(self):
print("汽车能跑起来了...")
2.3 对象的创建与使用
通过「类名()」即可实例化创建对象,通过「对象名.方法名()」调用类中的方法。
基础语法:
# 创建对象
对象名 = 类名()
# 调用方法
对象名.方法名()
案例:创建汽车对象并调用方法
# 1. 定义类
class Car:
def run(self):
print('能跑起来了...')
# 2. 创建对象
car = Car()
# 3. 调用方法
car.run()

2.4 self关键字
self是Python类方法中的第一个参数,也是面向对象的核心关键字之一。
- self的本质:指向调用该方法的对象实例本身。谁调用了这个方法,self就代表谁。
- self的作用:一个类可以创建N个对象,self用于区分不同的实例,在类内部访问对象的属性、调用其他方法。
验证:self与对象是同一个实例
class Car:
def run(self):
print(f'self的内存地址:{self}')
print('能跑起来了...')
# 创建第一个对象
car = Car()
print(f'car对象的内存地址:{car}')
car.run()
print('*' * 30)
# 创建第二个对象
car2 = Car()
print(f'car2对象的内存地址:{car2}')
car2.run()
运行结果中,car对象和self的内存地址完全一致,证明二者指向同一个实例:

类内部调用其他方法
在类的方法中调用同类的其他方法,必须通过self.方法名()实现:
class Car:
def run(self):
print('能跑起来了...')
def work(self):
# 类内部调用方法,通过 self.方法名()
self.run()
car = Car()
car.work()



⚠️ 注意
定义方法时self必须写在第一个参数位置;
调用方法时,不需要手动传递self参数,Python解释器会自动把调用对象传入。
3 对象属性的添加与访问
学习目标
- 掌握在类外部添加、获取对象属性的方法
- 掌握在类内部获取对象属性的方法
3.1 什么是属性
属性是对象的固有特征,比如人的姓名、年龄、身高、体重,汽车的颜色、轮胎数等,在代码中通过变量表示。
3.2 类外部操作属性
- 添加/修改属性:
对象名.属性名 = 属性值 - 获取属性:
对象名.属性名
示例:给汽车对象添加颜色、轮胎数属性
class Car:
def run(self):
print('能跑起来了...')
# 创建对象
car = Car()
# 类外部添加属性
car.color = "红色"
car.number = 4
# 类外部获取属性
print(f"车的颜色:{car.color}")
print(f"轮胎数量:{car.number}")
3.3 类内部获取属性
在类内部通过 self.属性名 获取对象的属性,通常封装为专门的方法对外提供访问。
示例:在类内部打印汽车信息
class Car:
def run(self):
print('能跑起来了...')
def show(self):
# 类内部通过 self 获取属性
print(f"车的颜色为:{self.color}")
print(f"轮胎个数为:{self.number}")
# 创建对象
car = Car()
# 外部设置属性
car.color = "红色"
car.number = 4
# 调用内部方法查看属性
car.show()
💡 提示
类外部动态添加属性的方式虽然灵活,但不规范。实际开发中,属性通常在构造方法__init__中统一初始化。
3.4 本节核心总结
- 属性:对应对象的特征,本质是对象的成员变量
- 属性操作
- 类外部:
对象名.属性名 = 值添加/修改;对象名.属性名获取 - 类内部:
self.属性名访问和修改
- 类外部:
阶段性总结
- 编程思想
- 面向过程:以步骤为核心,扩展性差
- 面向对象:一切皆对象,通过类与对象模拟现实世界
- 类与对象
- 类:抽象模板,使用
class 类名:定义,推荐大驼峰命名 - 对象:具象实体,通过
对象名 = 类名()创建,对象名.方法名()调用方法
- 类:抽象模板,使用
- self:指向调用方法的对象本身,类内部操作属性、调用方法都依赖 self
- 属性:对象的特征,类内外有不同的访问方式
4 核心魔法方法
学习目标
- 理解魔法方法的概念与特点
- 掌握
__init__()构造方法的用法 - 掌握
__str__()方法的作用与写法 - 掌握
__del__()析构方法的作用
4.1 魔法方法的概念
魔法方法是 Python 类中特殊的方法,名称被双下划线包裹,在特定场景下会由 Python 解释器自动调用,无需开发者手动触发。它们是Python面向对象的“魔力”所在。
通用格式:__魔法方法名__()
4.2 __init__():构造方法
__init__() 也叫构造方法,在创建对象时会自动调用,用于初始化对象的属性,是最常用的魔法方法。
无参构造方法
无需外部传参,在类内部直接给属性设置默认值。
class Car:
def __init__(self):
# 初始化属性
self.color = 'red'
self.number = 4
def show(self):
print(f'车身颜色:{self.color}')
print(f'车轮数:{self.number}')
# 创建对象,自动执行 __init__
car = Car()
car.show()

带参构造方法
通过外部传入参数动态初始化属性,灵活性更高,是实际开发中最常用的写法。
class Car:
def __init__(self, color, number):
self.color = color
self.number = number
def show(self):
print(f'车身颜色:{self.color}')
print(f'车轮数:{self.number}')
# 创建对象时传入参数
car = Car('black', 8)
car.show()

4.3 __str__():对象描述方法
默认情况下,print(对象) 会输出对象的内存地址。如果实现了 __str__() 方法,打印对象时会自动输出该方法返回的字符串,用于自定义对象的描述信息。
注意:
__str__()必须返回字符串类型的数据。
class Car:
def __init__(self):
self.color = '红色'
self.number = 4
def __str__(self):
return f'{self.color}的汽车,有{self.number}个车轮'
car = Car()
print(car)
-
未实现
__str__():输出内存地址
-
实现
__str__():输出自定义内容
4.4 __del__():析构方法
__del__() 也叫析构方法,在对象被销毁时自动调用(手动 del 删除对象,或程序执行结束时),用于释放资源、清理内存。
class Car:
def __init__(self, color):
self.color = color
def __del__(self):
print('自动调用了 __del__ 魔法方法')
car = Car('红色')
del car # 手动删除对象,触发 __del__

4.5 本节核心总结
- 魔法方法特点:双下划线包裹、特定时机自动调用
__init__():创建对象时自动调用,用于初始化属性,支持无参、带参两种形式__str__():print(对象)时自动调用,返回自定义的对象描述字符串__del__():对象销毁时自动调用,用于资源释放
5 面向对象综合案例
5.1 案例1:学生体重管理
需求描述:
小明初始体重 100kg,每跑步一次体重减少 0.5kg,每大吃大喝一次体重增加 2kg。用面向对象方式实现该逻辑。
# 1. 定义学生类
class Student:
def __init__(self):
self.weight = 100 # 初始体重
# 跑步方法
def run(self):
self.weight -= 0.5
print(f'跑步一次,体重变为 {self.weight} kg')
# 大吃大喝方法
def eat(self):
self.weight += 2
print(f'大吃大喝一顿,体重变为 {self.weight} kg')
# 2. 创建对象
xiaoming = Student()
# 3. 调用方法
xiaoming.run()
xiaoming.eat()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.eat()
5.2 案例2:烤地瓜
需求主线:
-
地瓜生熟状态随烤制时间变化
烤制时长 生熟状态 0-3分钟 生的 3-7分钟 半生不熟 7-12分钟 熟了 超过12分钟 烤糊了 -
支持自定义添加调料

# 1. 定义地瓜类
class SweetPotato:
def __init__(self):
self.cook_time = 0 # 累计烤制时间
self.cook_state = '生的' # 当前生熟状态
self.condi_list = [] # 添加的调料列表
# 烤制方法
def cook(self, time):
self.cook_time += time
# 根据总时长更新状态
if 0 <= self.cook_time < 3:
self.cook_state = '生的'
elif 3 <= self.cook_time < 7:
self.cook_state = '半生不熟的'
elif 7 <= self.cook_time < 12:
self.cook_state = '熟了'
elif self.cook_time >= 12:
self.cook_state = '烤糊了'
# 添加调料
def add_condi(self, condi):
self.condi_list.append(condi)
# 自定义对象输出
def __str__(self):
return f'这个地瓜烤了{self.cook_time}分钟,状态是{self.cook_state},添加了{self.condi_list}'
# 2. 创建对象并测试
potato = SweetPotato()
print(potato)
potato.cook(3)
potato.add_condi('蜂蜜')
print(potato)
potato.cook(5)
potato.add_condi('酱油')
print(potato)
potato.cook(6)
potato.add_condi('醋')
print(potato)

面向对象编程思路:
- 需求分析:从业务中提取实体
- 抽象设计:将实体封装为类,梳理属性与方法
- 代码实现:通过对象调用方法模拟业务逻辑
第二部分:Python面向对象高级
1 类的三种定义方式
Python中类的定义有三种写法,分为旧式类与新式类,Python3中统一推荐新式类写法。
| 写法 | 格式 | 说明 |
|---|---|---|
| 旧式类1 | class 类名: |
无括号,Python2中为旧式类 |
| 旧式类2 | class 类名(): |
空括号,本质和第一种一致 |
| 新式类(推荐) | class 类名(object): |
显式继承顶级基类object,功能最完整 |
# 写法1
class Teacher:
pass
# 写法2
class Teacher():
pass
# 写法3(推荐)
class Teacher(object):
pass
💡 说明
Python3中所有类默认继承object,三种写法效果基本一致。但显式书写class 类名(object):更符合规范,兼容性更好,也是行业通用写法。
2 继承:代码复用的核心
学习目标
- 理解继承的概念与作用
- 掌握单继承、多继承的语法
- 掌握子类重写父类方法的写法
- 掌握调用父类方法的两种方式
- 了解多层继承的结构
2.1 继承的概念
继承描述类与类之间的从属关系:子类继承父类后,可以直接拥有父类的全部属性和方法,无需重复编写相同代码,大幅提升代码复用率。
- 父类(基类):被继承的类
- 子类(派生类):继承父类的类,可以扩展自己独有的属性和方法
生活中的继承对应“子承父业”,子女可以继承父母的财产、技能,还能发展自己的能力。

基础语法
class 父类名(object):
# 父类成员
...
class 子类名(父类名):
# 子类自动拥有父类所有属性和方法
...
基础示例
# 父类
class Father(object):
def __init__(self):
self.gender = "男"
def walk(self):
print("爱好散步行走")
# 子类,继承父类
class Son(Father):
pass
# 子类对象直接调用父类的属性和方法
son = Son()
print(son.gender)
son.walk()
2.2 单继承
单继承:一个子类只继承一个父类,是最基础的继承形式。
案例:师徒传承
摊煎饼的老师傅将配方和技术传授给徒弟。
# 师父类
class Master(object):
def __init__(self):
self.kofu = '[古法煎饼配方]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
# 徒弟类,继承师父类
class Tudi(Master):
pass
# 徒弟对象直接拥有师父的技术
xiaoming = Tudi()
print(xiaoming.kofu)
xiaoming.make_cake()
2.3 多继承
多继承:一个子类同时继承多个父类,拥有所有父类的属性和方法。
案例:拜师学艺+培训班学习
小明既跟着老师傅学古法技术,又在培训班学新技术。
# 师父类
class Master(object):
def __init__(self):
self.kofu = '[古法煎饼配方]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
# 培训班类
class Heima(object):
def __init__(self):
self.kofu = '[AI煎饼配方]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
# 徒弟类,同时继承两个父类
class Tudi(Heima, Master):
pass
xiaoming = Tudi()
print(xiaoming.kofu)
xiaoming.make_cake()
MRO 方法解析顺序
当多个父类存在同名属性/方法时,子类默认使用第一个父类的成员。
可以通过类名.__mro__或类名.mro()查看方法解析顺序(Method Resolution Order),即Python查找成员的优先级顺序。
print(Tudi.__mro__)
print(Tudi.mro())

查找顺序:子类自身 → 按继承顺序从左到右的父类 → object基类,找不到则报错。
2.4 子类重写父类同名方法和属性
当父类的方法不能满足子类需求时,子类可以定义同名的方法,覆盖父类的实现,这就是方法重写(Override)。
重写后,子类对象调用该方法时,优先执行子类自己的实现。
案例:自研独创技术
小明学会两种技术后,钻研出自己的独创配方。
class Master(object):
def __init__(self):
self.kofu = '[古法煎饼配方]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
class Heima(object):
def __init__(self):
self.kofu = '[AI煎饼配方]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
# 子类重写同名属性和方法
class Tudi(Heima, Master):
def __init__(self):
self.kofu = '[独创技术]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
xiaoming = Tudi()
print(xiaoming.kofu)
xiaoming.make_cake()
2.5 调用父类方法的两种方式
子类重写父类方法后,如果还需要使用父类的原有实现,可以手动调用父类方法,有两种实现方式:
方式1:父类名直接调用
语法:父类名.方法名(self),适合多继承场景,可以精准指定调用哪个父类。
class Tudi(Heima, Master):
def __init__(self):
self.kofu = '[独创技术]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
# 调用师父类的技术
def master_make_cake(self):
Master.__init__(self)
Master.make_cake(self)
# 调用培训班的技术
def heima_make_cake(self):
Heima.__init__(self)
Heima.make_cake(self)
xiaoming = Tudi()
xiaoming.make_cake()
xiaoming.master_make_cake()
xiaoming.heima_make_cake()

方式2:super() 调用
语法:super().方法名(),自动按照 MRO 顺序查找父类方法,适合单继承场景,代码更简洁,维护性更好。
class Tudi(Heima):
def __init__(self):
self.kofu = '[独创技术]'
def make_cake(self):
print(f'使用{self.kofu}摊煎饼')
def heima_make_cake(self):
super().__init__()
super().make_cake()
xiaoming = Tudi()
xiaoming.heima_make_cake()
注意:
super()适合单继承使用,多继承场景推荐使用父类名直接调用的方式。
2.6 多层继承
继承支持多层传递:C 继承 B,B 继承 A,那么 C 自动拥有 A、B 的所有属性和方法,形成继承链。
案例:技术代代相传
小明退休后,将所有技术传授给自己的徒弟。
# 徒孙类,继承徒弟类
class Tusun(Tudi):
pass
xiaoxiaoming = Tusun()
print(xiaoxiaoming.kofu)
xiaoxiaoming.make_cake()
xiaoxiaoming.heima_make_cake()
xiaoxiaoming.master_make_cake()
2.7 本节核心总结
- 继承:子类拥有父类的所有属性和方法,实现代码复用
- 单继承:一个子类只有一个父类
- 多继承:一个子类有多个父类,同名成员按 MRO 顺序优先取第一个父类
- 方法重写:子类定义同名方法覆盖父类实现,优先调用子类方法
- 调用父类方法:
- 父类名.方法名(self):精准指定,适合多继承
- super().方法名():自动查找,适合单继承
- 多层继承:继承链逐层传递属性和方法
3 封装:隐藏细节,保障安全
学习目标
- 理解封装的深层含义
- 掌握私有属性、私有方法的定义方式
- 掌握私有成员的公共访问接口写法
3.1 封装的概念
封装不仅是把属性和方法写到类里,更核心的是权限控制:隐藏内部实现细节,仅对外暴露安全的访问接口,防止外部随意修改内部数据,保障数据安全与逻辑稳定。
3.2 私有属性
在属性名前加双下划线 __,即可设置为私有属性:
- 只能在类内部直接访问
- 类外部、子类都无法直接访问
- 对外提供
get_xxx()获取属性、set_xxx()修改属性的公共方法
案例:师傅的私房钱
师傅把技术传给徒弟,但私房钱不对外暴露。
class Prentice(object):
def __init__(self):
self.kongfu = "[独创煎饼技术]"
self.__money = 2000000 # 私有属性:私房钱
# 公共方法:获取私有属性
def get_money(self):
return self.__money
# 公共方法:修改私有属性
def set_money(self, money):
self.__money = money
3.3 私有方法
在方法名前加双下划线 __,即可设置为私有方法:
- 只能在类内部调用
- 对外提供公共方法来间接调用私有方法
案例:保密的制作工艺
独创配方的制作流程保密,只对外暴露成品制作的接口。
class Prentice(object):
# 私有方法:内部核心工艺
def __secret_make(self):
print("独门秘方制作流程...")
# 公共方法:对外暴露的接口
def make_cake(self):
self.__secret_make()
📌 封装的规范
- 私有属性:提供
get_xxx()获取、set_xxx()修改的公共方法- 私有方法:通过公有方法间接调用
- 核心目的:隐藏内部实现,对外提供可控、安全的访问入口
4 多态:灵活扩展的灵魂
学习目标
- 理解多态的概念
- 掌握多态的实现条件与好处
- 了解抽象类的作用与用法
4.1 多态的定义
多态即「多种状态」:同一个函数/接口,传入不同的对象,会执行不同的逻辑,得到不同的结果。
class Animal(object):
def speak(self):
pass
class Dog(Animal):
def speak(self):
print('汪汪汪')
class Cat(Animal):
def speak(self):
print('喵喵喵')
# 统一的调用接口
def make_noise(animal: Animal):
animal.speak()
# 传入不同对象,得到不同结果
dog = Dog()
cat = Cat()
make_noise(dog) # 汪汪汪
make_noise(cat) # 喵喵喵
4.2 多态成立的三个条件
- 有继承:存在父类与子类的继承关系
- 方法重写:子类重写父类的同名方法
- 父类引用指向子类对象:函数接收父类类型参数,实际传入子类对象
实战案例:战机对战平台
搭建固定的战斗平台,一代战机、二代战机无需修改平台代码即可接入。
# 父类:一代战机
class HeroFighter(object):
def power(self):
return 60
# 子类:二代战机
class AdvHeroFighter(HeroFighter):
def power(self):
return 80
# 敌军战机
class EnemyFighter(object):
def attack(self):
return 70
# 战斗平台(框架代码,固定不变)
def object_play(hero: HeroFighter, enemy: EnemyFighter):
if hero.power() > enemy.attack():
print('英雄战机胜利,敌机失败')
else:
print('英雄战机失败,敌机胜利')
# 测试
hero1 = HeroFighter()
hero2 = AdvHeroFighter()
enemy = EnemyFighter()
object_play(hero1, enemy) # 一代出战
object_play(hero2, enemy) # 二代出战
4.3 多态的核心价值
- 解耦合:框架代码与具体业务实现分离,互不影响
- 高扩展:新增子类时,无需修改框架代码,直接继承并重写方法即可兼容
- 大白话理解:继承是「孩子复用父辈的东西」,多态是「父辈定下的框架,不用修改就能适配孩子的新实现」
4.4 抽象类(接口)
抽象类是特殊的父类,其中的方法只有定义没有实现(方法体为 pass),相当于制定了一套接口标准,要求所有子类必须实现这些方法。
- 抽象类不能直接实例化
- 作用:做顶层设计,约束子类的行为规范,配合多态实现统一调用

案例:空调行业标准
# 抽象类:制定空调标准
class AC(object):
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_l_r(self):
"""左右摆风"""
pass
# 子类:美的空调,实现标准
class Midea_AC(AC):
def cool_wind(self):
print("美的空调核心制冷科技")
def hot_wind(self):
print("美的空调电热丝加热")
def swing_l_r(self):
print("美的空调无风感左右摆风")
# 子类:格力空调,实现标准
class GREE_AC(AC):
def cool_wind(self):
print("格力空调变频省电制冷")
def hot_wind(self):
print("格力空调电热丝加热")
def swing_l_r(self):
print("格力空调静音左右摆风")
# 统一调用接口
def make_cool(ac: AC):
ac.cool_wind()
# 测试
gree_ac = GREE_AC()
midea_ac = Midea_AC()
make_cool(gree_ac)
make_cool(midea_ac)
5 面向对象的其他特性:类属性、类方法与静态方法
学习目标
- 区分类属性与实例属性
- 掌握类方法、静态方法的定义与用法
5.1 实例属性
我们之前学习的属性都是实例属性,归每个对象所有:
- 类内部通过
self.属性名定义 - 类外部通过
对象名.属性名访问 - 每个对象的属性值相互独立,互不影响
class Phone(object):
def __init__(self):
self.brand = '华为' # 实例属性
phone = Phone()
phone.color = '紫色' # 外部添加实例属性
5.2 类属性
类属性归类本身所有,所有实例共享同一份数据,定义在类内部、方法外部。
- 推荐通过
类名.类属性名访问 - 适合存储所有对象共有的数据,节省内存
class Person(object):
count = 0 # 类属性:统计实例数量
def __init__(self, name):
self.name = name
Person.count += 1
# 访问类属性
print(Person.count)
5.3 实例属性 vs 类属性
- 实例属性:归每个对象所有,每个对象独立一份,通过
self.定义。适合存储每个对象独有的数据。 - 类属性:归类本身所有,所有实例共享同一份,定义在类内部、方法外部。适合存储所有对象共有的数据,节省内存。
class Person(object):
count = 0 # 类属性:统计实例总数
def __init__(self, name):
self.name = name # 实例属性
Person.count += 1
# 访问类属性
print(Person.count)
5.4 三类方法对比
Python的类中有三种常见方法:实例方法、类方法、静态方法,各自用途不同。
| 方法类型 | 装饰器 | 首参数 | 核心用途 | 调用方式 |
|---|---|---|---|---|
| 实例方法 | 无 | self |
操作实例属性、调用实例方法 | 对象名.方法名() |
| 类方法 | @classmethod |
cls |
操作类属性、调用类方法 | 类名.方法名() |
| 静态方法 | @staticmethod |
无默认参数 | 工具类功能,不依赖类和实例 | 类名.方法名() |
类方法
使用@classmethod装饰,第一个参数为cls,代表类本身,通常配合类属性使用。
class Dog(object):
__total = 10 # 私有类属性
@classmethod
def get_total(cls):
return cls.__total
# 调用类方法
print(Dog.get_total())
静态方法
使用@staticmethod装饰,不需要默认参数,不依赖类的任何数据,相当于写在类里的普通函数,适合工具类功能。
class Game(object):
@staticmethod
def show_menu():
print("=" * 20)
print("【1】开始游戏")
print("【2】暂停游戏")
print("【0】退出游戏")
# 调用静态方法
Game.show_menu()
全文总结
核心知识图谱
-
基础核心
- 类是模板,对象是实例,self指向调用方法的对象本身
- 三大魔法方法:
__init__初始化、__str__描述对象、__del__销毁对象
-
三大特性
- 封装:双下划线设置私有成员,对外提供公共接口,隐藏细节、保障安全
- 继承:子类复用父类代码,支持单继承、多继承、多层继承,可重写父类方法
- 多态:同一接口不同实现,解耦框架与业务,提升扩展性;抽象类做顶层标准
-
进阶特性
- 类属性所有实例共享,类方法操作类属性,静态方法实现工具功能
写在最后
面向对象不仅是语法,更是一种设计思维。入门阶段可以多从经典案例(烤地瓜、学生管理)入手,先熟悉语法;进阶阶段可以尝试用面向对象思想重构自己的旧代码,体会封装、继承、多态带来的优势。多练多思考,才能真正吃透面向对象的精髓。
更多推荐
所有评论(0)