一. 单继承
class A:pass # 父类,也叫基类,也叫超类class B:pass # 父类,也叫基类,也叫超类class AB_son(A,B):pass # 子类,也叫派生类class B_son(B):pass # 子类,也叫派生类
一个类可以被多个类继承一个类可以继承多个父类 -- python 独有的
print(AB_son.__bases__) # (, )print(B_son.__bases__) # ( ,)# 查看继承的是谁print(A.__bases__) # ( ,) -- 可以理解为类的祖宗 ;新式类在Python3中,任何没有父类的类,都是 object 的儿子 -- 在Python3中,没有继承父类,默认继承 object
所以:class A(object):passclass A:pass # 这两个完全相等
class Animal: def __init__(self, name, HP, aggr): self.name = name self.HP = HP self.aggr = aggrclass Dogs(Animal): def bite(self,person): person.HP -= self.aggrclass Person(Animal): def __init__(self, sex): self.sex = sexjin = 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.funcclass 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 += 100class 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.aggrclass 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 -= 1jin = 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 += 100class 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 eatingsuper(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): # 找的顺序:从左往右找 passd = D() # Ad.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中,新式类和经典类共存,且新式类要继承objectpython3中,只有新式类,默认继承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()