我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈
这里写目录标题
- 面相对象三大特性
- 封装
- 封装的概念
- 封装的好处
- 继承
- 继承的概念
- 继承的目的
- 继承的分类
- 单继承
- 多继承
- type类和object类
- 继承对资源的影响
- 资源的继承
- 资源的使用
- 继承的几种形态
- 资源继承的标准顺序
- 继承资源查找顺序的演化过程
- 资源的覆盖
- 资源的累加
面相对象三大特性
封装
封装的概念
- 将一些属性和相关方法封装在一个对象中,对外隐藏内部具体实现细节
- 类似于【电脑主机】,内部实现,外界不需要关心,外界只需要根据“内部提供的接口”去使用就可以
封装的好处
- 1、使用起来更加方便
- 把很多相关的功能封装成一个整体
- 类似于向外界提供一个工具箱
- 针对不同的场景,使用不同的工具箱就可以
- 2、保证数据的安全性
- 针对安全级别高的数据,可以设置成“私有”
- 可以控制数据位只读,外界无法修改
- 也可以拦截数据的写操作,进行数据验证和过滤
- 3、利于代码维护
- 如果后期,功能代码需要维护,则直接修改这个类内部代码即可
- 只要保证接口名称不变,外界则不需要做任何代码修改
- 前面讲的[私有化属性]、[只读属性]都是封装的体现
继承
继承的概念
- 一个类“拥有”另外一个类的“资源”的方式之一
- 拥有:并不是资源的复制,而是资源的“使用权”
- 资源:指“非私有的”属性和方法
- 继承关系中类的名称
- 被继承的类:父类、超类、基类
- 继承的类:子类、派生类
继承的目的
* 方便资源的重用
继承的分类
单继承
- 概念
- 仅仅继承了一个父类
- 语法
class Animal: pass # 单继承 class Dog(Animal): pass
多继承
- 概念
- 继承了多个父类
- 语法
class Animall: pass class Dog: pass # 多继承 class keji(Dog, Animall): pass
type类和object类
-
查看取指定类的父类(基类)
cls.__bases__
-
查看制定对象由哪个类创建(实例化)
- 类的本身也是对象
obj.__class__
-
示例
class Animal: pass class Dog: pass class Keji(Animal, Dog): pass d = Dog() d.eat = '肉' # 查看制定类的父类 print(Keji.__bases__) # (<class '__main__.Animal'>, <class '__main__.Dog'>) print(Dog.__bases__) # (<class 'object'>,) print(Animal.__bases__) # (<class 'object'>,) print(object.__bases__) # () print(int.__bases__) # (<class 'object'>,) print(float.__bases__) # (<class 'object'>,) print(str.__bases__) # (<class 'object'>,) print(bool.__bases__) # (<class 'int'>,) # 查看对象由谁创建 print(d.__class__) # <class '__main__.Dog'> print(d.eat.__class__) # <class 'str'> print(Keji.__class__) # <class 'type'> print(Dog.__class__) # <class 'type'> print(Animal.__class__) # <class 'type'> print(object.__class__) # <class 'type'> print(type.__class__) # <class 'type'> print(int.__class__) # <class 'type'> print(float.__class__) # <class 'type'> print(str.__class__) # <class 'type'> print(bool.__class__) # <class 'type'>
-
关系图
-
复习
- 元类:Type类(创建类对象的类)
- 经典类:不继承自object类的类
- 新式类:继承自object类的类
继承对资源的影响
资源的继承
- 在Python中,继承是指资源额使用权。资源能否被继承,其实就是在子类中能否访问到父类当中的这个资源(属性和方法)
- 类内部的公有属性/方法、受保护属性/方法、内置方法均可被继承,只有私有属性/方法不可以被继承
- 继承仅仅只是访问并不能被设置
公有 # a = 777 # 可以被继承 受保护 # _b = 888 # 可以被继承 私有 # __c = 999 # 不能被继承 内置 # __init__ # 可以被继承
- 查看示例
class Animal: a = 777 _b = 888 __c = 999 def t1(self): print('t1') def _t2(self): print('_t2') def __t3(self): print('__t3') def __init__(self): print('Animal __init__') class Person(Animal): def test(self): print(self.a) # 777 print(self._b) # 888 # print(self.__c) # 报错:AttributeError: 'Person' object has no attribute '_Person__c' self.t1() # t1 self._t2() # _t2 # self.__t3() # 报错:AttributeError: 'Person' object has no attribute '_Person__t3' self.__init__() # Animal __init__ p = Person() p.test()
资源的使用
继承的几种形态
- 单继承链
- 无重叠的多继承
- 有重叠的多继承
资源继承的标准顺序
- 单继承链
def C: pass def B(C): pass def A(B): pass
先从自身(A)内部查找 ——> 到父类(B)内部查找 ——> 到父类的父类(C)内部查找
- 无重叠的多继承(遵循单调原则)
def C2: pass def C1: pass def B2(C2): pass def B1(C1): pass def A(B1, B2): pass
先从自身(A)内部查找 ——> 到左侧父类(B1)内部查找 ——> 到左侧父类的父类(C1)内部查找 ——> 到右侧父类(B2)内部查找 ——> 到右侧父类的父类(C2)内部查找
- 有重叠的多继承
def C1: pass def B2(C1): pass def B1(C1): pass def A(B1, B2): pass
先从自身(A)内部查找 ——> 到左侧父类(B1)内部查找 ——> 到右侧父类(B2)内部查找 ——> 到父类的父类(C1)内部查找
- 继承资源查找顺序图
继承资源查找顺序的演化过程
-
Python2.2之前
-
仅存在经典类(不继承自object类)
-
继承资源查找顺序遵守MRO原则-深度优先(从左往右)
-
知识补充
- MRO(Method Resolution Order):方法解析顺序
- 深度优先:沿着一个继承链,尽可能的往深了去找
- 深度优先具体算法步骤
- 1、先把根节点压入栈中
- 2、每次从栈中弹出一个元素,搜索所有在它下一级的元素
- 3、重复第2个步骤,直到搜索不到下一级元素
-
深度优先 继承资源查找顺序图示
-
单继承
-
-
无重叠多继承
-
-
有重叠多继承
-
-
-
问题点
- 在2.2版本之前的这种深度优先的查找顺序模式下,有重叠的多继承在资源查找上就存在问题,违背了“重写可用原则”。
- B2如果重写了C1中的资源,那么通过这种模式拿到的资源,还是C1中的原始资源,并不能拿到最新的B2中重写的资源
-
Python2.2
-
产生了新式类(继承自object类的类)(Python2.2版本开始才有object类)
-
继承资源查找顺序遵守MRO原则
- 经典类:深度优先(从左到右)
- 新式类:在深度优先(从左到右)的算法基础上优化了一部分:如果产生重复元素,会保留最后一个,并且更尊重基类出现的先后顺序
-
经典类
- 三种模式的继承资源查找顺序与2.2版本之前一致,就不再做动态图解了
-
新式类
- 单继承模式的继承资源查找顺序与经典类的单继承模式一样,图解省略
- 无重叠继承模式在变成新式类之后,实际上也就变成了有重叠继承模式了,只是最终的父类是object类
-
-
注意点:
-
2.2版本这种查找顺序有点类似“广度优先模式”,但是并不是!
-
稍微了解一下“广度优先模式”
- 1、把根节点放到队列的末尾
- 2、每次从队列的头部取出一个元素,搜索这个元素所有的下一级元素,并将其放到队列的末尾(发现元素已经被处理过,则略过)
- 3、重复第2步,直到队列为空则结束
-
队列的进出原则:先进先出(区别于栈的先进后出原则)
-
单继承模式深度优先于广度优先是没有区别的,区别在于多继承模式
-
多继承模式
- 入栈是先右后左,出栈是先左后右(先进后出)
- 入队列是先左后右,出队列也是先左后右(先进先出)
-
有重叠多继承模式图解
-
-
无重叠多继承模式图解
-
-
Python2.3-2.7
-
Python3.x之后