4-13 object类,继承和派生( super) ,钻石继承方法

1,object 类

object
class A:
    '''
    这是一个类
    '''
    pass

a = A()
print(A.__dict__)  # 双下方法 魔术方法

创建一个空对象
调用init方法    —— 调用了么? 调用了
将初始化之后的对象返回调用处,
{'__module__': '__main__', '__doc__': '     这是一个类     ', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>}

 2,继承和派生

在类中当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

子类自己新建属性就是派生属性。

派生属性的产生方法有两种:

1,在子类里直接定义一个属性:父类名.__init__(self,.......) # 

def __init__(self,name,hp,ad,sex):#重写

Animal.__init__(self,name,hp,ad)

self.sex = sex

2,也可以用super().__init__(加属性)和上面的作用一样

# 在单继承中,super负责找到当前类所在的父类,在这个时候不需要再手动传self
class Animal:#定义一个类
    def __init__(self,name,hp,ad):#定义属性
        self.name = name     # 对象属性 属性
        self.hp = hp         #血量
        self.ad = ad         #攻击力
    def eat(self):#定义一个eat方法
        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__)
#
# 对象
# Person.attack(alex)   # alex.attack()

# 狗 kind
# tg = Dog('到哥',100,50,'藏獒')
# print(tg.__dict__)
View Code
在类内 使用 super()方法找父类的方法

3,钻石继承(多继承)

新式类 多继承 寻找名字的顺序 遵循广度优先
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()#C
        print('C')
class D(B,C):
    def func(self):
        super().func()   
        print('D')

d = D()
d.func()#a,c,b,d

4,super用法的小结:

super():
在单继承中就是单纯的寻找父类
在多继承中就是根据子节点 所在图 的 mro顺序找寻下一个类
遇到多继承和super
对象.方法
找到这个对象对应的类
将这个类的所有父类都找到画成一个图
根据图写出广度优先的顺序
再看代码,看代码的时候要根据广度优先顺序图来找对应的super

5,经典类和新式类的区别:

经典类 :在python2.*版本才存在,且必须不继承object
遍历的时候遵循深度优先算法
没有mro方法
没有super()方法
新式类 :在python2.X的版本中,需要继承object才是新式类
遍历的时候遵循广度优先算法
在新式类中,有mro方法
有super方法,但是在2.X版本的解释器中,必须传参数(子类名,子类对象)
class A(object):
    def func(self):
        print('A')
class B(A):
    def func(self):
        print('B')
class C(A):
    def func(self):
        print('C')
class D(B,C):
    def func(self):
        super().func()
        print('D')

d = D()
d.func()#B,D
print(D.mro())


原文地址:https://www.cnblogs.com/yzxing/p/8822386.html