0413 继承与派生,钻石继承

继承与派生

class Animal:
    def __init__(self,name,hp,ad):
        self.name = name     # 对象属性 属性
        self.hp = hp         #血量
        self.ad = ad         #攻击力
    def eat(self):
        print('eating in Animal')
        self.hp += 20

class Person(Animal):
    def __init__(self,name,hp,ad,sex):        # 重写
        # Animal.__init__(self,name,hp,ad)
        # super(Person,self).__init__(name,hp,ad)   # 在单继承中,super负责找到当前类所在的父类,在这个时候不需要再手动传self
        super().__init__(name,hp,ad)   # 在单继承中,super负责找到当前类所在的父类,在这个时候不需要再手动传self
        self.sex = sex      # 派生属性
        self.money = 100
    def attack(self,dog):   # 派生方法
        print("%s攻击了%s"%(self.name,dog.name))
    def eat(self):                         # 重写
        super().eat()  # 在类内 使用 super()方法找父类的方法
        print('eating in Person')
        self.money -= 50

class Dog(Animal):
    def __init__(self,name,hp,ad,kind):
        Animal.__init__(self,name,hp,ad)
        self.kind = kind    # 派生属性
    def bite(self,person):  # 派生方法
        print("%s咬了%s" % (self.name, person.name))

# 人 sex
alex = Person('alex',100,10,'female')   # 实例化
print(alex.__dict__)

父类有eat 子类没有
alex.eat() # 找父类的
子类有eat 不管父类中有没有
alex.eat() # 找子类的
当子类中有,但是我想要调父类的
Animal.eat(alex)          #指名道姓
super(Person,alex).eat()  # super(子类名,子类对象)方法   —— 一般不用
子类父类都有eat方法,我想执行父类的eat和子类的eat
alex.eat()  # 执行子类的eat
print(alex.__dict__)

钻石继承

新式类 多继承 寻找名字的顺序 遵循广度优先

 

super():
在单继承中就是单纯的寻找父类
在多继承中就是根据子节点 所在图 的 mro顺序找寻下一个类
遇到多继承和super
对象.方法
找到这个对象对应的类
将这个类的所有父类都找到画成一个图
根据图写出广度优先的顺序
再看代码,看代码的时候要根据广度优先顺序图来找对应的super
经典类 :在python2.*版本才存在,且必须不继承object
遍历的时候遵循深度优先算法
没有mro方法
没有super()方法
新式类 :在python2.X的版本中,需要继承object才是新式类
遍历的时候遵循广度优先算法
在新式类中,有mro方法
有super方法,但是在2.X版本的解释器中,必须传参数(子类名,子类对象)

原文地址:https://www.cnblogs.com/Mr-Murray/p/8823422.html