python对象特性对比_11-Python面向对象-面向对象三大特性

学习地址:

1.封装

概念

将一些属性和相关方法封装在一个对象中

对外隐藏内部具体实现细节

内部实现, 外界不需要关心

外界只需要根据"内部提供的接口"去使用就可以

好处

1. 使用起来更加方便

因为已经把很多相关的功能, 封装成一个整体

类似于像外界提供一个工具箱

针对于不同的场景, 使用不同的工具箱就可以

2. 保证数据的安全

针对于安全级别高的数据, 可以设置成"私有";

可以控制数据为只读

外界无法修改

也可以拦截数据的写操作

进行数据校验和过滤

3. 利于代码维护

如果后期, 功能代码需要维护, 则直接修改这个类内部代码即可;

只要保证接口名称不变; 外界不需要做任何代码修改

2.继承

概念

现实中的"继承"

子女继承父母的"财产资源"

编程中的"继承"

一个类"拥有"另外一个类的"资源"的方式之一

"拥有"

并不是资源的复制, 变成双份资源

而是, 资源的"使用权"

"资源"

指"非私有的"属性和方法

Dog类继承自Animal类

Dog

子类

派生类

Animal

父类

基类

超类

目的

方便资源重用

分类

单继承

概念

仅仅继承了一个父类

语法

class Dog(Animal):

pass

多继承

概念

继承了多个父类

语法

class child(Father, Mather):

pass

type和object区分

type和object

新式类和经典类

新式类

直接或者间接继承自object的类

经典类

没有直接或者间接继承自object的类

继承下的影响

资源的继承

明确

在Python中, 继承是指, 资源的使用权

所以, 测试某个资源能否被继承, 其实就是测试在子类当中, 能不能访问到父类当中的这个资源

结论

除下私有的属性和私有的方法, 其他的基本都能继承

公有属性/方法

受保护属性/方法

内置方法

资源的使用

1. 继承的几种形态

单继承链

一个子类只有一个父类

图示

无重叠的多继承链

继承链无交叉, 无公共父类

图示

有重叠的多继承链

继承链有交叉, 有公共父类

图示

2. 几种形态应该遵循的标准原则

单继承

遵循"从下到上的原则"

自己身上没有这个资源, 就到父类里面去找, 父类里面没有再往上找

无重叠的多继承

遵循"单调原则"

按照继承的先后顺序, 优先调用左侧继承链上的资源

有重叠的多继承

遵循"从下到上的原则"

简单理解就是

A继承B继承C

B重写了C类的方法, 那么A优先使用B类的方法

3. 针对于几种标准原则的方案演化

Python2.2之前

仅仅存在经典类

MRO原则

深度优先(从左往右)

问题

"有重叠的多继承"中, 违背"重写可用原则"

Python2.2

产生了新式类

MRO原则

经典类

深度优先(从左到右)

新式类

在深度优先(从左到右)的算法基础之上, 优化了一部分

如果产生重复元素, 会保留最后一个

并且, 更尊重基类出现的先后顺序

注意:

并不是"广度优先算法"

问题

无法检测出有问题的继承

有可能还会违背"局部优先"的原则

子类继承多个父类

如果子类没有, 应按照父类从左到右的顺序, 优先查找

例如

图示

按照"上述算法", 计算结果为

A -> C -> B -> D -> object

问题是: A继承 (B, C)

A中没有, 应该优先选择左侧的B呀

Python2.3-2.7

新式类经典类并存

MRO原则

经典类

深度优先(从左到右)

新式类

C3算法

Python3.x之后

MRO原则

新式类

C3算法

概念补充

MRO

MRO(Method Resolution Order)

方法解析顺序

深度优先

沿着一个继承链, 尽可能的往深了去找

具体算法步骤

1. 把根节点压入栈中

2. 每次从栈中弹出一个元素,搜索所有在它下一级的元素

把这些元素压入栈中

发现已经被处理, 则略过

3. 重复第2个步骤到结束为止

广度优先

沿着继承链, 尽可能往宽了去找

具体算法步骤

把根节点放到队列的末尾

每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾

发现已经被处理, 则略过

重复上面步骤

C3算法

真正步骤

两个公式

L(object) = [object]

L(子类(父类1, 父类2)) = [子类] + merge(L(父类1), L(父类2) , [父类1, 父类2])

注意

+ 代表合并列表

merge算法

1. 第一个列表的第一个元素

是后续列表的第一个元素

或者

后续列表中没有再次出现

则将这个元素合并到最终的解析列表中

并从当前操作的所有列表中删除

2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

3. 如果最终无法把所有元素归并到解析列表, 则报错

类似拓扑排序, 但并不是! 切记

具体算法步骤

选择一个入度为0的顶点并输出之;

从网中删除此顶点及所有出边。

资源的覆盖

包括

属性的覆盖

方法重写

原理

在MRO的资源检索链当中

优先级比较高的类写了一个和优先级比较低的类一样的一个资源(属性或方法)

到时候, 再去获取相关资源, 就会优先选择优先级比较高的资源;

而摒弃优先级比较低的资源; 造成"覆盖"的假象

注意事项

当调用优先级比较高的资源时, 注意self的变化

资源的累加

概念

在一个类的基础之上, 增加一些额外的资源

子类相比于父类, 多一些自己特有的资源

直接增加就好

在被覆盖的方法基础之上, 新增内容

方案1

在高优先级类的方法中, 通过"类名"调用低优先级类的方法

弊端

代码维护性差

容易产生重复调用

方案2

在低优先级类的方法中, 通过"super"调用高优先级类的方法

概念

是一个类

只有在新式类中有效

作用

起着代理的作用, 帮我们完成以下任务

沿着MRO链条, 找到下一级节点, 去调用对应的方法

问题

沿着谁的MRO链条?

找谁的下一个节点?

如何应对类方法, 静态方法以及实例方法的传参问题?

语法原理

super(参数1[, 参数2])

工作原理

def super(cls, inst):

mro = inst.__class__.mro()

return mro[mro.index(cls) + 1]

问题解决

沿着谁的MRO链条?

参数2

找谁的下一个节点?

参数1

如何应对类方法, 静态方法以及实例方法的传参问题?

使用参数2进行调用

常用具体语法形式

super(type, obj) -> bound super object;

requires isinstance(obj, type)

super(type, type2) -> bound super object;

requires issubclass(type2, type)

super()

Python3+

Python2.2+

注意

super 和父类(超类)没有实质性的关联

仅仅是沿着MRO链条, 找到下一级节点

保证调用形式的统一

要是类名调用, 全是类名调用

要是super调用, 全是super调用

3.多态

多态

一个类, 所延伸的多种形态

在继承的前提下; 使用不同的子类, 调用父类的同一个方法, 产生不同的功能

调用时的多种形态

多态在Python中的体现

鸭子类型

动态类型的一种风格

只要一个对象, 会走, 会游泳, 会叫; 那它就可以当做一个鸭子进行处理

关注点在于对象的"行为和属性"; 而非对象的"类型"

多态-强调

多态的理解

补充

抽象类, 抽象方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值