一、初识继承
1、引入继承
1 class A(object): 2 pass # 父类,基类,超类 3 4 class B: 5 pass # 父类,基类,超类 6 7 class A_son(A, B): 8 pass # 子类,派生类 9 10 class AB_son(A): 11 pass # 子类,派生类 12 13 # 一个类 可以被多个类继承 14 # 一个类 可以继承多个父类 —— python里 15 print(A_son.__bases__) 16 print(AB_son.__bases__) 17 print(A.__bases__) # python3 -新式类# 没有继承父类默认继承object
2、实例
1 class Animal: 2 def __init__(self, name, aggr, hp): 3 self.name = name 4 self.aggr = aggr 5 self.hp = hp 6 self.func() # 谁来初始化,就调谁的func方法 7 8 def func(self): 9 print('animal func') 10 11 12 class Dog(Animal): 14 def func(self): 15 print('dog func') 16 17 def bite(self, person): 18 person.hp -= self.aggr 19 21 d = Dog('dig', 22, 33)
3、增加功能
狗类 吃 喝 看门(guard)
鸟类 吃 喝 下蛋(lay)
1 class Animal: 2 def __init__(self): 3 print('执行Animal.__init__') 4 self.func() 5 6 def eat(self): 7 print('%s eating' % self.name) 8 9 def drink(self): 10 print('%s drinking' % self.name) 11 12 def func(self): 13 print('Animal.func') 14 15 16 class Dog(Animal): 17 def guard(self): 18 print('guarding') 19 20 def func(self): 21 print('Dog.func') 22 23 24 dog = Dog() 25 26 27 class Bird(Animal): 28 def __init__(self, name): 29 self.name = name 30 31 def lay(self): 32 print('laying')
二、单继承
以上实例都是一个类只继承一个类,即单继承。
1、继续原来的例子,增加吃药回血功能
1 class Animal: 2 def __init__(self,name,aggr,hp): 3 self.name = name 4 self.aggr = aggr 5 self.hp = hp 6 7 def eat(self): 8 print('吃药回血') 9 self.hp+=100 10 11 class Dog(Animal): 12 def __init__(self,name,aggr,hp,kind): 13 Animal.__init__(self,name,aggr,hp) # 14 self.kind = kind # 派生属性 15 def eat(self): 16 Animal.eat(self) # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类 17 self.teeth = 2 18 def bite(self,person): # 派生方法 19 person.hp -= self.aggr 20 21 jin = Dog('金老板',100,500,'吉娃娃') 22 jin.eat() 23 print(jin.hp)
增加一个继承类
1 class Person(Animal): 2 def __init__(self,name,aggr,hp,sex): 3 Animal.__init__(self,name,aggr,hp) 4 self.sex = sex # 派生属性 5 self.money = 0 # 派生属性 6 7 def attack(self,dog): 8 dog.hp -= self.aggr 9 10 def get_weapon(self,weapon): 11 if self.money >= weapon.price: 12 self.money -= weapon.price 13 self.weapon = weapon 14 self.aggr += weapon.aggr 15 else: 16 print("余额不足,请先充值") 17 alex = Person('alex',1,2,None) 18 alex.eat() 19 print(alex.hp) 20 21 jin.bite(alex) 22 print(alex.hp)
2、总结
父类中没有的属性 在子类中出现 叫做派生属性
父类中没有的方法 在子类中出现 叫做派生方法
只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
如果父类 子类都有 用子类的
如果还想用父类的,单独调用父类的:
父类名.方法名 需要自己传self参数
super().方法名 不需要自己传self
正常的代码中 单继承 === 减少了代码的重复
继承表达的是一种 子类是父类的关系
1 class Animal: 2 def __init__(self,name,aggr,hp): 3 self.name = name 4 self.aggr = aggr 5 self.hp = hp 6 def eat(self): 7 print('吃药回血') 8 self.hp+=100 9 10 class Dog(Animal): 11 def __init__(self,name,aggr,hp,kind): 12 super().__init__(name,aggr,hp) # 只在新式类中有,python3中所有类都是新式类 13 self.kind = kind # 派生属性 14 def eat(self):print('dog eating') 15 16 jin = Dog('金老板',200,500,'teddy') 17 print(jin.name) 18 jin.eat() 19 super(Dog,jin).eat()
三、多继承
新式类(python3中都是新式类)中的继承顺序 : 广度优先
非新式类,深度优先
本处都是在python3中运行。
1、普通多继承例子
1 class F: 2 def func(self): print('F') 3 class A(F):pass 4 # def func(self): print('A') 5 class B(A): 6 pass 7 # def func(self): print('B') 8 class E(F):pass 9 # def func(self): print('E') 10 class C(E): 11 pass 12 # def func(self): print('C') 13 14 class D(B,C): 15 pass 16 # def func(self):print('D') 17 18 d = D() 19 # d.func() 20 print(D.mro())
先找最靠近自己的父类,以此类推!
2、钻石多继承
1 class A(object): 2 def func(self): print('A') 3 4 class B(A): 5 def func(self): 6 super().func() 7 print('B') 8 9 class C(A): 10 def func(self): 11 super().func() 12 print('C') 13 14 class D(B,C): 15 def func(self): 16 super().func() 17 print('D') 18 19 b = D() 20 b.func() 21 print(B.mro())
3、总结
新式类 继承object类的才是新式类 广度优先
经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
print(D.mro())
D.mro()
单继承 : 子类有的用子类 子类没有用父类
多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
经典类中 深度优先
新式类中 广度优先
python2.7 新式类和经典类共存,新式类要继承object
python3 只有新式类,默认继承object
经典类和新式类还有一个区别 mro方法只在新式类中存在
super 只在python3中存在
super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的