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