Python学习之路_day_24(面向对象之继承)
面向对象之继承:
- 继承介绍
什么是继承:
继承是一种创建新类的方式,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类。
子类会“”遗传”父类的属性,从而解决代码重用问题。
继承的特性:子类可以遗传和重用父类的属性。
python中的类分为两种:新式类,经典类
新式类: 但凡继承了object的类Foo,以及该类的子类...都是新式类。
在python3中一个类即便是没有显式地继承任何类,默认就会继承object,即python3中所有的类都是新式类。
经典类:没有继承object的类,以及该类的子类...都是经典类
在python2中才区分新式类与经典类,在python2中一个类如果没有显式地继承任何类,也不会继承object。
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
- 继承与抽象
继承描述的是子类与父类之间的关系,是一种什么是什么的关系。要找出这种关系,必须先抽象再继承。
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。
抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类。
- 继承与重用
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时。
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用。
- 属性查找优先级
在单继承背景下属性的查找优先级:对象->对象的类->父类->父类.....
在多继承背景下属性的查找优先级:
如果一个子类继承多个分支(多个分支没有共同继承一个非object的类)
此时属性的查找优先级是:对象->对象的类->按照从左往右的顺序一个分支一个分支的找下去。
菱形继承问题:
新式类 : 广度优先查找,从左往右一个分支一个分支的查找,在最后一个分支才去查找顶级类
经典类 : 深度优先查找,从左往右一个分支一个分支的查找,在第一个分支就查找顶级类
新式类(广度优先)
经典类(深度优先)
- 在子类派生出的新方法中重用父类功能
方式一:即父类名.父类方法()
指名道姓地引用某一个类中的函数
总结:
1. 与继承无关
2. 访问是类的函数,没有自动传值的效果
方式二:super()
super()必须在类中用
在python2中:super(自己的类名,自己的对象)
在python3中:super()
调用该函数会得到一个特殊的对象,该对象专门用来访问父类中的属性,!!!完全参照mro列表!!!!
总结:
1. 严格依赖继承的mro列表
2. 访问是绑定方法,有自动传值的效果
6.继承原理(python如何实现的继承)
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类