继承

继承

在子类派生的新方法中如何重用父类的功能

指名道姓

# 方式一:指名道姓     调用某一个类下的函数=》不依赖于继承关系

class OldboyPeople:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def f1(self):
        print('%s say hello' %self.name)


class Teacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary):
        OldboyPeople.__init__(self,name,age,sex)  # 指名道姓,该传几个参数就传几个参数

        self.level = level
        self.salary=salary

tea_obj=Teacher('egon',18,'male',10,3000)
print(tea_obj.__dict__)  
# {'name': 'egon', 'age': 18, 'sex': 'male', 'level': 10, 'salary': 3000}

严格依赖继承--super()

# 方式二:super()  调用父类提供给自己的方法=》严格依赖继承关系
#        调用super()会得到一个特殊的对象,该对象会参照发起属性查找的那个类的mro,去当前类的父类中找属性

class OldboyPeople:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def f1(self):
        print('%s say hello' %self.name)


class Teacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary):
        # super(Teacher,self).__init__(name,age,sex)
        super().__init__(name,age,sex) # 调用的是方法,自动传入对象

        self.level = level
        self.salary=salary

print(Teacher.mro())
# [<class '__main__.Teacher'>, <class '__main__.OldboyPeople'>, <class 'object'>]

tea_obj=Teacher('egon',18,'male',10,3000)
print(tea_obj.__dict__)
# {'name': 'egon', 'age': 18, 'sex': 'male', 'level': 10, 'salary': 3000}

# self.__init__(name,age,sex) 
# 因为self严格指向自己,self在Teacher类里面,因此self是一个teacher对象,就进入了一个递归了
---------------------------------------------------------
Traceback (most recent call last):
  File "C:/Users/baobao/PycharmProjects/untitled1/hello.py", line 23, in <module>
    tea_obj=Teacher('egon',18,'male',10,3000)
  File "C:/Users/baobao/PycharmProjects/untitled1/hello.py", line 15, in __init__
    self.__init__(name, age, sex)
TypeError: __init__() missing 2 required positional arguments: 'level' and 'salary'
# super()的用法
# 针对Python2,必须这么用,并且super只能用于新式类当中
super(Teacher,self).__init__(name,age,sex)

# 对于python3,可以简写,super什么参数都不用传,直接加括号
super().__init__(name,age,sex)

# __init__(self,...)不用传参self,因为super()得到的是一个对象,自动传入对象

# super会创建一个特殊对象,会参照当前类的MRO,去当前类的父类去找,即从第二个位置往后找,找到OldboyPeople
print(Teacher.mro())
# [<class '__main__.Teacher'>, <class '__main__.OldboyPeople'>, <class 'object'>]


# super()案例
# A和B之间没有继承关系

class A:
    def test(self):
        print('from A')
        super().test()  # 参照MRO,去B中找,尽管没有继承关系

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

class C(A,B):
    pass


obj=C()
obj.test()
# 分析查找顺序
# 1.obj先从自己找,没有
# 2.去C里面找,没有
# 3.按照发起属性查找的那个类的mro往下找下去,发起者是C类,因此参照C去找A
# 重点:super属性查找不能简单的理解为直接去爹(父类)找,参照的是属性查找发起者的mro;因此即便A和B没有继承关系,找完A也能接着去找B
print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
# 4.参照C去找A,找到test,打印from A;紧接着遇到super,当前在A,因此查找当前类的父类;而当前类的父类是属性发起者的MRO规定的(super去找A类的爹参照MRO,而MRO规定A的爹是B)
# 5.super().test()去B找,打印from B

from A
from B
# 强调一下,子类中用父类功能有两种方式,推荐用super
# 哪种都可以用,但是不能混着用

# 指名道姓:和MRO压根没关系,压根不参考MRO
# super:严格依赖MRO,但是不是参考自己的MRO,而是参考属性查找发起者那个类的MRO,去找当前类的父类


class A:
    def test(self):
        print('from A')
        super().test1() # 参照C的MRO,,MRO规定B就是A的爹,因此去B找;但是B中没有test1,因此直接报错

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

class C(A,B):
    def test1(self):
        print('from C')

obj=C()
obj.test()

print(C.mro())
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

from A
Traceback (most recent call last):
  File "C:/Users/baobao/PycharmProjects/untitled1/hello.py", line 15, in <module>
    obj.test()
  File "C:/Users/baobao/PycharmProjects/untitled1/hello.py", line 4, in test
    super().test1()
AttributeError: 'super' object has no attribute 'test1'

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容