python学习之老男孩python全栈第九期_day024知识点总结——单继承、多继承
一. 单继承
class A:pass # 父类,也叫基类,也叫超类 class B:pass # 父类,也叫基类,也叫超类 class AB_son(A,B):pass # 子类,也叫派生类 class B_son(B):pass # 子类,也叫派生类
一个类可以被多个类继承
一个类可以继承多个父类 -- python 独有的
print(AB_son.__bases__) # (<class '__main__.A'>, <class '__main__.B'>) print(B_son.__bases__) # (<class '__main__.B'>,) # 查看继承的是谁 print(A.__bases__) # (<class 'object'>,) -- 可以理解为类的祖宗 ;新式类 在Python3中,任何没有父类的类,都是 object 的儿子 -- 在Python3中,没有继承父类,默认继承 object
所以: class A(object):pass class A:pass # 这两个完全相等
class Animal: def __init__(self, name, HP, aggr): self.name = name self.HP = HP self.aggr = aggr class Dogs(Animal): def bite(self,person): person.HP -= self.aggr class Person(Animal): def __init__(self, sex): self.sex = sex jin = Dogs('金老板',200,500) # Dogs里面没有__init__,就去父类找... alex = Person('alex') print(jin.name)
狗类 鸟类 共同点:都是动物,能吃能喝 不同点: 狗:看门 鸟:下蛋 class Animal: def __init__(self): print('执行Animal.__init__') self.func() def eat(self,name): self.name = name print('%s eating'%self.name) def drink(self,name): self.name = name print('%s drinking'%self.name) def func(self): print('Animal.func()') class Dogs(Animal): def guard(self): print('guarding') def func(self): print('Dogs.func') dog = Dogs() # 执行Animal.__init__ # Dogs.func class Bird(Animal): def __init__(self,name): self.name = name print('%s'%self.name) def lay(self): print('laying') bird = Bird('小小鸟') dog.drink('金毛') # bird.drink() # dog.guard() bird.lay()
人狗大战 class Animal(): def __init__(self, name, HP, aggr): self.name = name self.HP = HP self.aggr = aggr def eat(self): print('%s吃药回血'%self.name) self.HP += 100 class Dogs(Animal): def __init__(self,name, HP, aggr, kind): Animal.__init__(self, name, HP, aggr) # self.kind = kind # 派生属性 def eat(self): Animal.eat(self) # 如果既想实现新的功能,也想实现父类的功能,还需要在子类中调用父类(self必须要传) self.teeth = 2 def bite(self,person): # 派生方法(父类没有,子类有的) person.HP -= self.aggr class Person(Animal): def __init__(self,name, HP, aggr, sex): Animal.__init__(self,name, HP, aggr) self.sex = sex # 派生属性 self.money = 0 # 派生属性 def attack(self,dog): dog.HP -= self.aggr def get_weapon(self,weapon): if self.money >= weapon.price: self.money -= weapon.price self.weapon = weapon self.aggr += weapon.aggr else: print('余额不足, 请充值') class Weapon: # 定义一个装备类 def __init__(self, name, aggr, naijiu, price): self.name = name self.aggr = aggr self.naijiu = naijiu self.price = price def hand_18(self, peason): if self.naijiu > 0: peason.HP -= self.aggr * 2 self.naijiu -= 1 jin = Dogs('金老板',100,2,'泰迪') print(jin.name) jin.eat() print(jin.HP) print(jin.teeth) alex = Person('alex',200,2,'不详') alex.eat() print(alex.HP) jin.bite(alex) print(alex.HP)
父类中没有的属性,在子类出现,叫做派生属性 父类中没有的方法,在子类出现,叫做派生方法 只要是子类的对象调用,子类中有的名字一定用子类的,子类中没有才找父类的,如果父类中还没有就报错 如果父类,子类都有,用子类的 如果还想用父类的,就要单独调用父类的: 父类名.方法名 -- 需要自己传self参数 super().方法名 -- 不需要自己传self 正常的代码中,单继承 --》 减少了代码的重复性 继承表达的是一种 子类是父类的关系 而组合表达的是一种 谁有谁的关系 比如 :老师 有 生日,组合关系。不能说老师是生日
class Animal(): def __init__(self, name, HP, aggr): self.name = name self.HP = HP self.aggr = aggr def eat(self): print('%s吃药回血'%self.name) self.HP += 100 class Dogs(Animal): def __init__(self,name, HP, aggr, kind): super().__init__(name, HP, aggr) # super():在单继承中,找到父类, -- 只在新式类中有,python3中所有的类都是新式类... self.kind = kind # 派生属性 def eat(self):print('dog eating') jin = Dogs('金老板',100,2,'泰迪') print(jin.name) jin.eat() # dog eating super(Dogs,jin).eat() # 金老板吃药回血
super
在类内部使用时,不需要写括号里面的默认参数
在外部使用时,需要写 Dog,jin 默认参数
二. 多继承
class A: def func(self):print('A') class B: def func(self):print('B') class C: def func(self):print('C') class D(A, B, C): # 找的顺序:从左往右找 pass d = D() # A d.func()
# 钻石问题 class A: def func(self):print('A') class B(A): pass # def func(self):print('B') class E: def func(self): print('E') class C(E): pass def func(self):print('C') class D(B, C): pass # def func(self):print('D') d = D() d.func()
# 六边形 class F: def func(self):print('F') class A(F): pass # def func(self):print('A') class B(A): pass # def func(self):print('B') class E(F): def func(self):print('E') class C(E): pass def func(self):print('C') class D(B, C): pass # def func(self):print('D') d = D() d.func() print(D.mro()) # 查看继承顺序
多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么? 新式类(python3)的继承顺序:广度优先 经典类(python2.7)的继承顺序:深度优先(一条路走到黑) python2.7中,新式类和经典类共存,且新式类要继承object python3中,只有新式类,默认继承object 经典类和新式类还有一个区别:mro方法,只有新式类有,super方法只在python3中有
super的本质:不是直接找父类,而是根据调用者的节点位置的广度优先顺序来的
class A: def func(self):print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B, C): def func(self): super().func() print('D') d = D() d.func()