- 概念
- 将一些属性和相关方法封装在一个对象中
- 对外隐藏具体实现细节:内部实现,外部只需要根据”内部提供的接口“去使用
- 好处
- 使用起来更加方便:因为已经把很多相关的功能封装成一个整体;类似于向外界提供了一个工具箱;针对不同的场景,使用不同的工具箱就可以
- 保证数据的安全:针对安全级别高的数据,可以设置为”私有“;可以控制数据为只读:外界无法修改;也可以拦截数据的写操作:进行数据校验和过滤
- 有利于代码维护:如果后期代码需要维护,则直接修改这个类内部代码即可
- 只要保证接口名称不变,外界不需要做任何代码修改
-
概念
- 现实中的”继承“:子女继承父母的”财产资源“
- 编程中的”继承“:
- 一个类”拥有“另外一个类的”资源“的方式之一
- ”拥有“:并不是资源的复制,而是资源的”使用权“
- ”资源“:指”非私有的“属性和方法
- Dog类继承自Animal类:
-
目的
-
分类
- 单继承
- 多继承
-
type和object区分
-
继承下的影响
-
资源的继承
- 明确
- 在python中,继承是指资源的使用权
- 测试某个资源能否被继承,其实就是测试在子类中,能不能访问到父类当中的这个资源
- 结论
- 除了私有属性和方法,其他的基本都能继承(公有属性和方法、受保护的属性和方法、内置方法)
- 明确
-
资源的使用
import inspect inspect.getmro()#1.查看某一个类的资源查找顺序 B.__mro__#2.查看某一个类的资源查找顺序 B.mro()#3.查看某一个类的资源查找顺序
- 继承的几种形态
- 单继承链:深度优先遍历
- 无重叠的多继承链:深度优先遍历
- 有重叠的多继承链:广度优先遍历
- 几种形态应该遵循的标准原则
- 针对几种标准原则的方案演化
- python2.2之前
- 仅仅存在经典类
- MRO原则:深度优先
- 问题:”有重叠的多继承“中,违背了”重写可用原则“
- python2.2
- 产生了新式类
- MRO原则:
- 经典类:深度优先
- 新式类:在深度优先的算法基础下,优化了一部分:如果产生重复元素,会保留最后一个(重复元素的最后一个),并且更尊重基类出现的先后顺序(注意:并不是”广度优先算法“)
- 问题:
- 无法检测出有问题的继承
- 有可能还会违背”局部优先“的原则
- python2.3-2.7
- 新式类经典类并存
- MRO原则:
- 经典类:深度优先
- 新式类:C3算法
- python3之后
- MRO原则:新式类(没有经典类):C3算法
- 概念补充
- MRO:Method Resolution Order方法解析顺序
- 深度优先:沿着一个继承链,尽可能地往深里去找
- 把根节点压入栈中
- 每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中(发现已经被处理,则略过)
- 重复第二个步骤到结束为止
- 广度优先:沿着继承链,尽可能往宽里去找
- 把根节点放到队列的末尾
- 每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们都放到队列的末尾(发现已经被处理,则略过)
- 重复上面的步骤
- C3算法
- 真正步骤
- 两个公式
- L(object) = [object]
- L(子类(父类1,父类2)) = [子类] + merge(L(父类1),L(父类2),[父类1,父类2])
- 注意:
- +代表合并列表
- merger算法
- 第一个列表的第一个元素:是后续列表的第一个元素,或后续列表中没有再出现,则将这个元素合并到最终的解析列表中,并从当前操作的所有列表中删除
- 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则
- 如果最终无法把所有元素归并到解析列表,则报错
- 两个公式
- 类似于拓补排序,但不是拓扑排序
- 真正步骤
- python2.2之前
- 继承的几种形态
-
资源的覆盖
- 包括:属性的覆盖、方法的重写
- 原理:
- 在MRO的资源检索链当中
- 优先级比较高的类写了一个和优先级比较低的类一样的一个资源(属性或方法)
- 到时候,再去获取相关资源,就会优先选择优先级比较高的资源;而摒弃优先级比较低的资源;造成”覆盖“的假象
- 注意事项:当调用优先级比较高的资源时,注意self、cls的变化
-
资源的累加
-
概念:在一个类的基础上,增加一些额外的资源
-
子类相比于父类,多了一些自己特有的资源
-
在被覆盖的方法基础之上,新增内容
-
方案一:通过类名调用初始化方法(会出现重复调用的情况;不利于代码维护)
-
方案二:在低优先级类的方法中,通过”super“调用高优先级类的方法
-
概念:是一个类;只有在新式类中有效
-
作用:起着代理的作用,作用是沿着MRO链,找到下一级节点,去调用对应的方法
-
问题:
- 沿着谁的MRO链?
- 找谁的下一个节点?
- 如何应对类方法、静态方法以及实例方法的传参问题?
-
语法原理:
-
super(参数1[,参数2])
-
工作原理
def super(cls,inst): mro = inst.__class__.mro() return mro[mro.index(cls) + 1] -
问题解决
- 沿着谁的MRO链:参数2
- 找谁的下一个节点:参数1
- 如何应对类方法、静态方法以及实例方法的传参问题:使用参数2进行调用
-
-
常用具体语法形式:
- python2.2+:略
- python3+:super()
-
注意:
-
-
-
-
- 多态
- 一个类所延申的多种形态
- 调用时的多种形态:在继承的前提下,使用不同的子类,调用父类的同一个方法,产生不同的功能
- 多态在python中的体现
- 鸭子类型
- 动态类型的一种风格
- 只要一个对象,会走、会叫、会游泳,那它就可以当作一个鸭子进行处理
- 关注点在于对象的“行为和属性”;而非对象的“类型”
- 所以,在python中,没有真正意义上的多态;也不需要多态
- 鸭子类型
-
抽象类
- 一个抽象出来的类,并不是某一个具体的类
- 不能直接创建实例的类:创建会报错
-
抽象方法
- 抽象出来的一个方法
- 不具备具体实现,不能直接调用:子类不实现会报错
-
python中的实现
-
无法直接支持,需要借助一个模块:import abc
-
设置类的元类为:abc.ABCmeta
-
使用装饰器修饰抽象方法:@abc.abstractmethod
import abc class Animal(object,metaclass=abc.ABCmeta): @abc.abstractmethod def jiao(self): pass class Dog(Animal): def jiao(self): print("汪汪汪") class Cat(Animal): def jiao(self): print("喵喵喵") def test(obj): obj.jiao() d = Dog() d.jiao()
-



