一、继承
类的继承跟现实生活中的父子、孙子、重孙子等一样,父类又被称为基类
在python中继承分为单继承和多继承
class Father: pass class Mother: pass class Son(Father): #单继承 pass class Son(Father, Mother): #多继承(可以不止两个) pass
子类集成了父类的所有类属性
class Father: money = 100 def __init__(self,name, age): self.name = name self.age = age def play_son(self): print("%s正在打儿子"%self.name) class Son(Father): pass f1 = Father("蔡徐坤","30") print(Son.money) Son.play_son(f1)
子类定义的属性如果跟父类同名了,优先拿自己定义的值
class Father: money = 100 def __init__(self,name, age): self.name = name self.age = age def play_son(self): print("%s正在打儿子"%self.name) class Son(Father): money = 10 def play_son(): print("测试") f1 = Father("蔡徐坤","30") print(Son.money) Son.play_son()
因为下面例子中Son没有init函数,所以实例化Son的时候会触发继承的父类的init,所以需要传入两个参数
class Father: money = 100 def __init__(self,name, age): self.name = name self.age = age def play_son(self): print("%s正在打儿子"%self.name) class Son(Father): money = 10 f1 = Father("蔡徐坤","30") print(Son.money) s1 = Son("自己", "18") #实例化Son的时候会触发继承的父类的init,所以需要传入两个参数 print(s1.name) print(s1.__dict__) print(Son.__dict__)
二、什么时候用继承?
1. 当类之间有显著不同时,并且较小的类是较大类所需要的组件时,用组合比较好
2. 当类之间有很多相同的功能来提取这些共同的功能做成基类,用继承比较好
派生:
一个类,继承了父类,而自己又有独特的功能称为派生
继承同时具有的两种含义:
1、继承基类的方法,并且做出自己的改变或扩展(代码重用)
#这种继承意义不大,甚至是有害的,因为它使得子类与基类出现强耦合,代码块之间往往越独立越好
2、声明某个子类兼容于某基类,定义一个接口类,子类继承接口,并且实现接口中定义的方法
三、【接口继承】
概念:定义一个基类,当基类当中把自己的方法定义成接口函数,利用装饰器的方式,
只要来一个子类继承它,就必须实现基类中的方法
接口:就是函数或者说方法
接口里的方法不用实现,只是为了规范子类。
通过引入abc模块,强制子类的方法必须与基类一致,若不一致,则报错!
import abc class All_file(metaclass = abc.ABCMeta): @abc.abstractclassmethod def read(self): pass @abc.abstractclassmethod def write(self): pass class Disk(All_file): def read(self): print('disk read') def write(self): print('disk write') class Cdrom(All_file): def read(self): print('cdrom read') #此处少定义一个write函数,所以会报错 c1 = Cdrom()
而Disk类中的方法与基类一致,则正常调用
import abc class All_file(metaclass = abc.ABCMeta): @abc.abstractclassmethod def read(self): pass @abc.abstractclassmethod def write(self): pass class Disk(All_file): def read(self): print('disk read') def write(self): print('disk write') class Cdrom(All_file): def read(self): print('cdrom read') d1 = Disk() d1.read()
四、继承顺序
继承顺序分为两种:1. 深度优先 2. 广度优先
基类没有任何继承关系的叫 经典类
基类继承 object 的叫新式类
在python 3中,都是新式类,新式类按广度优先
class A: #基类 def test(sslf): print('A') class B(A): def test(self): print('B') class C(A): def test(self): print('C') class D(C): def test(self): print('D') class E(C): def test(self): print('C') class F(D, E): def test(self): print('F') f1 = F() f1.test()
调用test方法时,先从自身开始找,找不到的话,找继承的父类,新式类按广度优先
F--->D--->B--->E--->C---->A
内置方法查看继承顺序
python到底是如何实现继承,对于你定义的每一个类,python会计算出一个方法解析(MRO)列表,
这个MRO列表就是一个简单的所有基类的线性顺序列表
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上
就是合并所有父类的MRO列表并遵循如下三条规则:
1. 子类会先于父类被检查
2. 多个父类会根据它们在列表中的顺序被检查
3. 如果对下一个类存在两个合法的选择,选择第一个父类
print(F.__mro__)
而在python2中,有经典类之分,经典类继承按 深度优先
即:F--->D---->B--->A---->E----->C