一、简介
''' 什么是继承 继承是一种新建类的方式,新建的类称为子类或者派生类,被继承的类称为父类或基类或超类 子类会继承父类的属性,从而解决代码重用问题 Python支持多继承 注意: 在Python3中,如果没有显示继承任何类,默认继承object类 object类提供了一些基础的功能 print(Fclass1.__bases__) (<class 'object'>,) 在Python2中,如果没有显示的继承任何类,也不会继承object类 print(Fclass1.__bases__) () 在Python中类分为两种 新式类: 但凡继承object的类,以及该类的子类都是新式类 在Python3中所有的类都是新式类 经典类: 没有继承object类,以及该类的子类都是经典类 只有python2中才存在经典类,因为在python2中没有显示的继承任何类,也不会继承object类 为何要用继承 减少代码冗余 '''
二、定义基类和子类
class Fclass1: # 定义父类 addr = 'shanghai' class Fclass2: commany = 'haymaker' # 定义分类 class sub2(Fclass1): # 单继承 基类是Fclass1 派生类或子类是sub2 name = 'fred' class sub1(Fclass1, Fclass2): # 多继承,基类是Fclass1和Fclass2,用逗号隔开 name = 'Fred' # 查看继承 print(Fclass1.__bases__) ''' (<class 'object'>,) # 基类没有继承任何类,默认继承object类 ''' print(sub1.__bases__) # __base__是查看所有继承的基类 ''' (<class '__main__.Fclass1'>, <class '__main__.Fclass2'>) ''' print(object.__dict__)
三、单继承背景下的属性查找
''' 单继承背景下的属性查找顺序: 对象————对象的类————父类 ''' class OperationSystem: os = 'linux' class WebService(OperationSystem): def __init__(self, name, version): self.name = name # self.os=OperationSystem.os # self.os='ubuntu' self.version = version web = WebService('nginx', '1.2.1') # web.os = 'windows' # 在对象中新增os属性 print(web.os) ''' windows 对象和对象的类中都有os属性,但还是从对象中先查找,即找到os='windows' ''' ''' ubunto 注释掉web中的os属性,就从对象的类中查找,即在WebService类中找到os='ubuntu' ''' ''' linux 注释掉WebService类中的os属性,就从父类中查找,即在OperationSystem类中找到os='linux' '''
四、多继承背景下的属性查找
''' 多继承背景下熟悉查找顺序 对象————对象的类————按照从左到右一个个分之查找下去 ''' 以上多继承的属性查找顺序为: obj—A—B—E—C—G—D—I

# 第三层 class E: # x = 555 pass class G: # x = 666 pass class I: x = 777 pass # 第二层 class B(E): # x = 222 pass class C(G): # x = 333 pass class D(I): # x = 444 pass # 第一层 class A(B, C, D): # x = 111 pass obj = A() # obj.x=0 print(obj.x)
菱形继承问题
新式类中会子类会按照MRO调用排在自己下一个的类中的方法,即:
print(A.mro()) # 只有新式类才会有MRO列表
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.G'>, <class '__main__.D'>, <class '__main__.I'>, <class '__main__.J'>, <class 'object'>]

# 第四层: class J: x = 888 pass # 第三层 class E(J): # x = 555 pass class G(J): # x = 666 pass class I(J): # x = 777 pass # 第二层 class B(E): # x = 222 pass class C(G): # x = 333 pass class D(I): # x = 444 pass # 第一层 class A(B, C, D): # x = 111 pass obj = A() # obj.x = 0 print(obj.x)

# coding:utf8 # 第四层: class J: # x = 888 pass # 第三层 class E(J): # x = 555 pass class G(J): # x = 666 pass class I(J): x = 777 pass # 第二层 class B(E): # x = 222 pass class C(G): # x = 333 pass class D(I): # x = 444 pass # 第一层 class A(B, C, D): # x = 111 pass obj = A() # obj.x = 0 print(obj.x)
''' 新式类: 属性查找顺序:obj——A——B——E——C——G——D——I——J 广度优先查找,在最后一个分支查找顶级类 根据MRO列表查找 经典类: 属性查找顺序:ojb——A——B——E——J——C——G——D——I 深度优先查找,在第一个分支就查找顶级类 '''
五、在子类派生出的新方法中重用父类功能的方式(减少代码冗余)
方式1:
''' 指明道姓的访问某一个类的函数 注意: 1.该方式与继承是没有关系的 2.访问是某一个类的函数,没有自动传值的效果 ''' class OperationSystem: def __init__(self, name, company, version): self.name = name self.company = company self.version = version class Support(OperationSystem): def __init__(self, name, company, version, language): OperationSystem.__init__(self,name, company, version) # 遵守函数传参的个数 self.language = language windows=Support('oracle','oracle','12.1','english') print(windows.__dict__) ''' {'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'} '''
方式2
''' super():只能在子类中用 Python2:super(自己的类名,对象自己) Python3:super() 注意: 1.该方式严格依赖于继承的mro列表 2.访问绑定方法,有自动传值的效果 ''' class OperationSystem: def __init__(self, name, company, version): self.name = name self.company = company self.version = version class Support(OperationSystem): def __init__(self, name, company, version, language): super().__init__(name, company, version) # OperationSystem.__init__(name,company,version) self.language = language windows = Support('oracle', 'oracle', '12.1', 'english') print(windows.__dict__) ''' {'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'} '''

# coding:utf8 ''' super():只能在子类中用 Python2:super(自己的类名,对象自己) Python3:super() 注意: 1.该方式严格依赖于继承的mro列表 2.访问绑定方法,有自动传值的效果 ''' class OperationSystem(object): # Python2中父类必须手动继承object类 否则会报错super() argument 1 must be type, not classobj def __init__(self, name, company, version): self.name = name self.company = company self.version = version class Support(OperationSystem): def __init__(self, name, company, version, language): super(Support, self).__init__(name, company, version) # OperationSystem.__init__(name,company,version) self.language = language windows = Support('oracle', 'oracle', '12.1', 'english') print(windows.__dict__) ''' {'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'} '''