Python面向对象:封装、继承、多态
作为Python面向对象编程(OOP)的三大核心特性,封装、继承、多态是从编程新手进阶到熟练开发者的必备知识。它们不是晦涩的理论,而是能让代码更简洁、复用性更强、扩展性更好的实用工具。
一、什么是面向对象?
在讲三大特性前,先明确两个基础概念:
- 类(Class):是模板,比如「人类」,定义了属性和行为的规则;
- 对象(Object):是实例,比如「张三」「李四」,是类的具体实现。
- 也就是说类是抽象,而对象是一个看得见摸得着的实体
面向对象的核心思想:把数据和操作数据的方法绑定在一起,用对象管理代码,而不是零散的函数和变量。
而封装、继承、多态,就是实现这一思想的三大支柱。
二、特性一:封装 —— 保护数据,只留必要接口
1. 什么是封装?
把类的核心数据和方法藏起来,只对外暴露安全的调用接口。
就像我们用手机,只需要按屏幕、点按钮,不需要知道内部芯片、电路的工作原理——内部细节被「封装」了,既保护了数据安全,又简化了使用。
2. Python封装的实现
Python没有严格的private关键字,用下划线约定实现封装:
- 单下划线
_属性/方法:保护成员,约定不建议外部直接访问; - 双下划线
__属性/方法:私有成员,外部无法直接访问(强制封装)。
3. 代码示例
classPerson:def__init__(self,name,age):self.name=name# 公有属性:外部可直接访问self.__age=age# 私有属性:外部无法直接访问(封装核心)# 对外暴露的方法:安全获取私有属性defget_age(self):returnself.__age# 对外暴露的方法:安全修改私有属性(可加校验)defset_age(self,new_age):if0<new_age<150:# 封装校验逻辑,防止非法数据self.__age=new_ageelse:print("年龄不合法!")# 创建对象p=Person("张三",20)# 1. 公有属性可直接访问print(p.name)# 输出:张三# 2. 私有属性无法直接访问(会报错)# print(p.__age) # 报错:AttributeError# 3. 通过暴露的方法访问/修改私有属性print(p.get_age())# 输出:20p.set_age(25)# 合法修改print(p.get_age())# 输出:25p.set_age(200)# 输出:年龄不合法!封装的优点
- 保护数据安全:防止外部随意修改核心数据;
- 简化使用:外部只需调用接口,无需关心内部逻辑;
- 便于维护:内部逻辑修改,不影响外部调用。
三、继承
1.单继承.py
# 单继承:子类只继承一个父类classFather:def__init__(self):self.money=1000defdrive(self):print("爸爸会开车")# Son 类 继承 Father类classSon(Father):# 子类可以拥有自己的属性和方法defstudy(self):print("儿子会学习")# 创建子类对象s=Son()# 子类对象直接使用父类的属性和方法print(s.money)s.drive()s.study()2.重写.py
# 方法重写:子类定义和父类同名的方法,覆盖父类实现classFather:defdrive(self):print("爸爸开燃油车")# 子类重写父类方法classSon(Father):defdrive(self):print("儿子开电动车")s=Son()# 调用的是子类重写后的方法s.drive()3.super()调用父类的同名方法
# super():在子类中调用父类的同名方法classFather:defdrive(self):print("爸爸开燃油车")classSon(Father):defdrive(self):# 调用父类的drive方法super().drive()print("儿子开电动车")s=Son()s.drive()4.多继承.py
# 多继承:一个子类继承多个父类classFather:defdrive(self):print("爸爸会开车")classMother:defcook(self):print("妈妈会做饭")# 子类同时继承两个父类classSon(Father,Mother):passs=Son()s.drive()s.cook()5.练习方法查找顺序
# 方法查找顺序 MRO:从当前类 -> 左父类 -> 右父类 -> objectclassA:deffunc(self):print("A类方法")classB(A):deffunc(self):print("B类方法")classC(B):pass# 查看类的继承顺序print(C.__mro__)c=C()c.func()6演示python的伪多态
# Python 伪多态(鸭子类型):不强制继承,只要有同名方法就可以调用classDog:defspeak(self):print("汪汪汪")classCat:defspeak(self):print("喵喵喵")# 统一调用接口,不需要继承同一个父类defmake_speak(animal):animal.speak()make_speak(Dog())make_speak(Cat())7.isinstance
# isinstance:判断对象是否是某个类(或子类)的实例classFather:passclassSon(Father):passs=Son()f=Father()print(isinstance(s,Son))# Trueprint(isinstance(s,Father))# True(子类对象属于父类类型)print(isinstance(f,Son))# False8.成员属性和类属性
# 成员属性(实例属性):每个对象独立拥有# 类属性:所有对象共享,属于类classPerson:# 类属性species="人类"def__init__(self,name):# 成员(实例)属性self.name=name# 访问类属性print(Person.species)p1=Person("张三")p2=Person("李四")# 实例访问类属性print(p1.species)print(p2.name)四、多态 —— 同一行为,不同表现
1. 什么是多态?
一句话总结:不同子类对象调用同一个父类方法,表现出不同的行为。
前提:继承 + 方法重写。
就像「动物」都会叫,但「狗」是汪汪叫,「猫」是喵喵叫——同一个「叫」的行为,不同子类有不同实现。
2. 代码示例
# 父类:动物classAnimal:defspeak(self):pass# 父类定义方法模板,不具体实现# 子类1:狗classDog(Animal):# 重写speak方法defspeak(self):print("汪汪汪!")# 子类2:猫classCat(Animal):# 重写speak方法defspeak(self):print("喵喵喵!")# 统一调用函数:接收任意Animal子类对象defanimal_speak(animal):animal.speak()# 创建不同子类对象dog=Dog()cat=Cat()# 同一方法,不同表现(多态核心)animal_speak(dog)# 输出:汪汪汪!animal_speak(cat)# 输出:喵喵喵!多态的优点
- 灵活通用:统一调用接口,无需区分具体子类;
- 易于扩展:新增子类时,无需修改原有调用代码;
- 降低耦合:代码依赖父类,不依赖具体子类。
五、三大特性核心总结
| 特性 | 核心思想 | 作用 |
|---|---|---|
| 封装 | 藏细节,露接口 | 保护数据,简化使用 |
| 继承 | 子类复用父类 | 减少重复代码,层级清晰 |
| 多态 | 同一行为,不同表现 | 代码灵活,易于扩展 |
用封装保护数据,用继承复用代码,用多态实现灵活扩展——这就是Python面向对象的核心逻辑。
六、实战:三合一综合示例
# 父类:员工(封装+继承基础)classEmployee:def__init__(self,name,salary):self.name=name self.__salary=salary# 封装私有属性defget_salary(self):returnself.__salarydefwork(self):pass# 多态模板方法# 子类1:程序员(继承+重写)classProgrammer(Employee):defwork(self):print(f"{self.name}正在写代码,月薪{self.get_salary()}元")# 子类2:产品经理(继承+重写)classPM(Employee):defwork(self):print(f"{self.name}正在写需求,月薪{self.get_salary()}元")# 多态调用defwork(emp):emp.work()# 创建对象p=Programmer("张三",20000)pm=PM("李四",18000)# 统一调用,不同表现work(p)# 输出:张三正在写代码,月薪20000元work(pm)# 输出:李四正在写需求,月薪18000元结语
- 封装:隐藏内部细节,仅暴露安全接口,保护数据安全;
- 继承:子类复用父类属性和方法,支持方法重写,减少代码冗余;
- 多态:基于继承和方法重写,同一接口实现不同行为,提升代码灵活性;
封装、继承、多态不是纸上谈兵的理论,而是写高质量Python代码的必备工具:
- 做项目时,用封装保护核心数据;
- 有重复代码时,用继承快速复用;
- 需要灵活扩展时,用多态简化逻辑。
