一、继承
1、含义:继承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题。
2、特点:继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,而父类又可以成为基类或超类,新建的类称为派生类或之类。
3、继承的分类
Python中类的继承可分为单继承和多继承。
# 单继承 class Hero: ‘‘‘ 父类 ‘‘‘ def __init__(self,nickname,aggressivity,life_valid): self.nickname = nickname self.aggressivity = aggressivity self.life_valid = life_valid def attack(self,target): target.life_valid -= self.aggressivity if target.life_valid <= 0: print(‘%s is died‘%target.nickname) class Gaylen(Hero): #单继承,基类是Hero,派生类是Gaylen ‘‘‘ 继承父类 ‘‘‘ pass class Hand_of_Knoxus(Hero):#单继承,基类是Hero,派生类是Hand_of_Knoxus
‘‘‘ 继承父类 ‘‘‘
pass
herol = Gaylen(‘大盖伦‘,60,300)
hero2 = Hand_of_Knoxus(‘诺手‘,70,280)
print(herol.__dict__) # {‘nickname‘: ‘大盖伦‘, ‘aggressivity‘: 60, ‘life_valid‘: 300}
herol.attack(hero2)
print(hero2.life_valid) # 220
#多继承
class Parent1: #定义父类一
pass
class Parent2: #定义父类二
pass
class son1(Parent1,Parent2): #Python支持多继承,用逗号分隔多个继承的类
pass
#查看继承
print(son1.__base__
)# __base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
#(<class ‘__main__.Parent1‘>)
print(son1.__bases__
) #(<class ‘__main__.Parent1‘>,
<class ‘__main__.Parent2‘>
)
4、单继承中对象属性的查找顺序
<1>对象自身属性(__init__方法)里查找
<2>对象自身里没有,在自己的类里找
<3>自己的类里没有,在父类里查找
# 属性查找 class Father: def f1(self): print(‘from Father.f1‘) def f2(self): print(‘from Father.f2‘) self.f1() # 等价于person.f1(),查找:person自身->自身的类(Son) class Son(Father): def f1(self): print(‘from Son.f1‘) person = Son() print(person.__dict__) # {} 自身没有定义属性 person.f2() # 单继承查找顺序:person自身—>自身的类(Son)->父类(Father)
二、派生
1、含义:
派生:子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),对象属性查找中按照自身,后类,再父类的顺序,当某些属性自身类中有而父类无或者两者都有时,优先选择自身类中的属性。
2、实例:
class Hero: ‘‘‘ 父类 ‘‘‘ def __init__(self,nickname,aggressivity,life_valid): self.nickname = nickname self.aggressivity = aggressivity self.life_valid = life_valid def attack(self,target): target.life_valid -= self.aggressivity if target.life_valid <= 0: print(‘%s is died‘%target.nickname,‘\nfrom Hero.attack‘) class Gaylen(Hero): ‘‘‘ 继承父类 ‘‘‘ camp = ‘Desmarcia‘ def attack(self,target): target.life_valid -= self.aggressivity if target.life_valid <= 0: print(‘%s is died‘%target.nickname,‘\nfrom Gaylen.attack‘) class Hand_of_Knoxus(Hero): ‘‘‘ 继承父类 ‘‘‘ camp = ‘Desmarcia‘
herol = Gaylen(‘大盖伦‘,80,190) hero2 = Hand_of_Knoxus(‘诺手‘,100,150) herol.attack(hero2) herol.attack(hero2) ‘‘‘ 输出: 诺手 is died from Gaylen.attack ‘‘‘
三、继承的实现原理
1、Python对于你定义的每一个类,会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。
2、为了实现继承,Python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。简单来说就是合并所有父类的MRO列表并遵循下述原则:
<1>子类会优先于父类被检查
<2>多个子类会根据它们在列表中的顺序被检查。
<3>如果对下一个类存在两个合法的选择,选择第一个父类
注意:
在Java和C#只能继承一个父类,而Python中子类可以继承多个父类,如果继承了多个父类,那么属性的查找方式有两种,分别是:深度优先和广度优先。
通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的
成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为父类,也就是基类。
四、多继承下的属性查找(广度优先)
class A(object): def test(self): print(‘from A‘) class B(A): # def test(self): # print(‘from B‘) pass class C(A): # def test(self): # print(‘from C‘) pass class D(B): # def test(self): # print(‘from D‘) pass class E(C): # def test(self): # print(‘from E‘) pass class F(D,E): # def test(self): # print(‘from F‘) pass f = F() f.test() # 查找顺序:f->F类->D类->B类->E类->C类->A类 print(F.mro()) # 新式类中才有这个属性可以查看线性列表,经典类没有 # [<class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.B‘>, # <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>]
五、经典类和新式类
1、在Python2中-》经典类:没有继承object的类,以及他的子类都称之为经典类。 深度优先查找
如下:
class Father: pass class Son(Father): pass
2、在Python2中-》新式类:有继承object的类,以及他的子类都称之为新式类。 广度优先查找
如下:
class Father(object): pass class Son(Father): pass
3、在Python3中-》新式类(无经典类之分):一个类没有继承object类,就默认继承object。 广度优先查找
class Father(): pass print(Father.__bases__) # (<class ‘object‘>,) 在Python中,每个类有一个__bases__属性,列出其基类
补充: