Python面向对象之派生

发布时间 2024-01-12 21:19:51作者: Lea4ning

派生

【一】概要

  • "派生"(Derivation)是指在面向对象编程中,通过创建新的类,基于已有的类(通常称为父类或基类)来构建新的类,以获取和扩展父类的属性和方法。在这个过程中,新创建的类称为子类或派生类。
  • 通俗来讲,派生是指,子类继承父类,派生出自己的属性与方法,并且重用父类的属性与方法

【二】常用方法

【1】指名道姓

class 父类():
    def __init__(self,参数1,参数2):
        self.参数1 = 参数1
        self.参数2 = 参数2
        
class 派生类(父类):
    '''此处派生是为了,继承父类的初始化属性,并初始化自己的属性'''
    def __init__(self,参数1,参数2,派生类自己的参数):
        # 不依赖于继承,不是父类也可以重写
        父类.__init__(self,参数1,参数2)
        # 需要将self传入

【2】super()

class 父类():
    def __init__(self,参数1,参数2):
        self.参数1 = 参数1
        self.参数2 = 参数2
        
class 派生类(父类):
    '''此处派生是为了,继承父类的初始化属性,并初始化自己的属性'''
    def __init__(self,参数1,参数2,派生类自己的参数):
        # 依赖于继承
        # 使用super方法就可以默认向上查找父类中的属性并重写
        super().__init__(参数1,参数2)
        # 不需要传递self

【三】详解

【1】指名道姓

class Father(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.father_run =self.run

    def run(self):
        print(f"Father.run")

class Son(Father):
    def __init__(self,name,age,level):
        '''指名道姓的声明'''
        Father.__init__(self,name,age)
        self.level = level
    def run(self):
        # 方法可能不太明显,因为可以解释为调用
        Father.run(self)
        print(f"Son.run")

s = Son('son',5,'son')
print(s.__dict__)   # {'name': 'son', 'age': 5, 'run': <bound method Son.run of <__main__.Son object at 0x00000152873E3FA0>>, 'level': 'son'}
s.run()   # 将会输出两条,而不是一条
# Father.run
# Son.run

【2】super()

class Father(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.father_run =self.run

    def run(self):
        print(f"Father.run")

class Son(Father):
    def __init__(self,name,age,level):
        super().__init__(name,age)
        self.level = level
    def run(self):
        # super会更直观一些
        super().run()
        print(f"Son.run")

s = Son('son',5,'son')
print(s.__dict__)   # {'name': 'son', 'age': 5, 'run': <bound method Son.run of <__main__.Son object at 0x00000152873E3FA0>>, 'level': 'son'}
s.run()   # 将会输出两条,而不是一条
# Father.run
# Son.run

class A:
    def run(self):
        super().run()
        print("A.run")
        
class B:
    def run(self):
        print("B.run")
        
class C(A,B):
    pass

c = C()
c.run()
# B.run
# A.run

【3】super()mro()

  • super() 用于以一种一致而可预测的方式调用父类的方法,它遵循方法解析顺序(MRO)以确定应该查找哪个类的方法。
'''引:c.test() 的结果是什么?报错还是输出内容'''
class A:
    def test(self):
        # super是向上继承,而A是新式类,默认继承object
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass

c = C()
c.test()
class A:
    def test(self):
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass

c = C()
c.test()   # from B

# super() MRO以确定应该查找哪个类的方法。
# mro() 可以用来查看属性查找顺序
print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
  • C 的 MRO 是由类定义中基类的顺序确定的。在这种情况下是 C(A, B),所以 MRO 是 [C, A, B]。当你调用 c.test() 时,它会在 MRO 列表中的第一个类中(C)查找 test 方法,如果找不到,它会移到下一个类(A),以此类推。
  • 因此,在类 Atest 方法中,当你使用 super().test() 时,它会在 MRO 中的下一个类中查找 test 方法,也就是 B。这样,它确保了方法是从 MRO 中的下一个类中调用的,提供了一种一致而可预测的导航类层次结构的方式。