- 接 上一篇
面向对象的三大特性
- 封装
- 继承
- 多态
封装
- 封装就是对对象的成员进行访问限制
- 封装的三个级别
- 私有 (private)
- 受保护 (protected)
- 公开 (public)
- 判别对象的位置
- 对象内部
- 对象外部
- 子类中
private
- 私有成员是最高级别的封装,只能在当前类或对象中访问
- 给成员添加前置双下划线即可,如
__age
class Person:
name = "YorkFish" # name 是共有的成员
__age = 18 # __age 是私有成员
- Python 的私有不是真私有,是一种称为
name mangling
的改名策略 - 可以使用
对象._classname__attributename
访问,如下
p = Person()
print(p._Person__age)
protected
- 受保护的封装是将对象成员进行一定级别的封装
- 在类中或者子类中都可以进行访问
- 在外部不可以
- 封装方法:给成员添加前置单下划线即可,如
_sum
public
- 公共的封装实际对成员没有任何操作,任何地方都可以访问
继承
概念与作用
- 概念:使一个类可以获得另一个类中的成员属性和成员方法
- 作用
- 减少代码量
- 增加代码复用
- 可以设置类与类直接的关系
继承与被继承
- 概念
- 用于继承的类叫子类,也叫派生类
- 被继承的类叫父类,也叫基类、超类
- 继承与被继承一定存在一个
is-a
关系
特征
- 所有的类都继承自
object
类,即所有的类都是object
类的子类 - 子类一旦继承父类,就可以使用父类中除私有成员外的所有内容
- 子类继承父类后并没有将父类成员完全复制到子类中,而是通过引用关系访问调用
- 子类中可以定义独有的成员属性和方法
- 子类中定义的成员和父类成员如果相同,则优先使用子类成员
- 子类如果想扩充父类的方法
- 可以在定义新方法的同时访问父类成员来进行代码重用
- 可以使用
父类名.父类成员
的格式来调用父类成员 - 也可以使用
super().父类成员
的格式来调用
查找顺序
-
优先查找自己的变量
- 如果本类有定义,则不再继续向上查找;如果没有,则查找父类
- 如果本类中的“构造函数”没有定义,则自动查找调用父类的“构造函数”
-
ps
- 严格来说,
def __init__():
并非真正意义上的“构造函数” - 它是一类特殊的函数,在类进行实例化之前进行调用
- 如果定义了“构造函数”,则实例化时使用“构造函数”,不查找父类“构造函数”
- 如果没定义,则自动查找父类“构造函数”
- 如果子类没定义,且父类的“构造函数”带参数,则构造对象时的参数应该按父类参数构造
- 严格来说,
super
super
不是关键字,而是一个类super
的作用是获取 MRO(MethodResolustionOrder) 列表中的第一个类super
与父类之间没任何实质性关系,但通过super
可以调用到父类super
能继承并调用父类的方法
单继承与多继承
- 单继承:每个类只能继承一个类
- 优点:传承有序,逻辑清晰,语法简单,隐患少
- 缺点:功能不能无限扩展,只能在当前唯一的继承链中扩展
- 多继承:每个类允许继承多个类
- 优点:类的功能扩展方便
- 缺点:继承关系混乱
菱形继承
- 也称钻石继承
- 多个子类继承自同一个父类,这些子类由被同一个类继承,于是继承关系图形成一个菱形图谱
- 关于多继承的 MRO
- MRO 就是多继承中用于保存继承顺序的一个列表
- Python 本身采用 C3 算法来计算多继承的菱形继承的顺序
- MRO 列表的计算原则:
- 子类永远在父类前面
- 如果多个父类,则根据继承语法中括号内类的书写顺序存放
- 如果多个类继承了同一个父类,“孙子类”中只会选取继承语法括号中第一个父类的父类
构造函数
- 在对象进行实例化的时候,系统自动调用的一个函数叫构造函数
- 通常,此函数用来对实例对象进行初始化
- 构造函数一定要有,如果没有,则自动向上查找,按照 MRO 顺序,直到找到为止
多态
概念
- 同一个对象在不同情况下有不同的状态
- 多态不是语法,是一种设计思想
多态与多态性
术语 | 释义 |
---|---|
多态 | 同一事物的多种形态 |
多态性 | 一种调用方式,不同的执行效果 |
Mixin 设计模式
- 主要采用多继承方式对类的功能进行扩展
- 使用多继承语法来实现 Minxin
- 使用 Mixin 实现多继承的时候需非常小心
- 首先,它必须表示某一单一功能,而不是某个物品
- 其次,职责必须单一,如果有多个功能,则写多个 Mixin
- Mixin 不能依赖于子类的实现
- 子类及时没有继承这个 Mixin 类也能照样工作,只是缺少了某个功能
Mixin 的优点
- 使用 Mixin 可以在不对类进行任何修改的情况下,扩充功能
- 可以方便地组织和维护不同功能组件的划分
- 可以根据需要任意调整功能类的组合
- 可以避免创建很多新的类,导致类的继承混乱