python3面向对象(2)之super()

super()是一个什么鬼?干什么用的?打开菜鸟教程看一下super()的简介;第一句话就是:super()函数是用来调用父类(超类)的一个方法。嗯哦;原来是一个函数可以返回一个父类的方法:于是我就这样理解了,那么如果是多继承呢,是返回所有父类的被调用的方法吗?一个疑问?看看下面的代码(先定义一个人类,然后定义一个男人,一个女人,一个儿子)

class Person(object):     #定义一个人类,继承objec
    def __init__(self):
        print("我要好好学习")

    def study(self):
        print("我要学好语言")


class man(Person):   #定义一个男人,继承人类
    def __init__(self):
        print("我是男人我要好好学习")

    def study(self):
        print("我要学好数学")
        


class woman(Person):    #定义一个女人,继承人类
    def __init__(self):
        print("我是女人我要好好学习")

    def study(self):
        print("我要学好英语")
      

class son(man,woman):  #定义一个儿子,继承男人和女人
    def __init__(self):
        print("我是儿子我要好好学习")

    def study(self):
        print("我要学好化学和物理")
# woman.study(self) # man.study(self) super().study() # def study1(self): # print("我要学好英语") son1 = son() son1.study() # son1.study1()
解释:先定义一个人类,定义一个方法:我要学好语言;然后定义一个男人:我要学好数学;再定义一个女人:我要学好英语;最后定义一个儿子学好化学和物理;在定义方法的时候我们都使用了study函数;所以子类的函数
会覆盖父类的函数;最后实例化一个son1的对象调用study函数只会输出:我要学好化学和物理;但是这个时代光会这两门也不行啊;还得学好英语啊,那么怎么办呢? ok 简单

在这个son的类中增加一个study1函数不就完了嘛,嗯,对确实完了;但是这样却增加了不必要的代码啊,学习英语这件事woman类中不是有了吗?我们不能直接使用这里的吗?当然可以,于是有了第二种方法:

在son的类中的study函数中增加了 woman.study(self) 这句好相当于直接调用woman类中的study函数 同理也可以直接调用man类中的study函数;这样就不用创建新函数了;这种等于直接调用。我们还可以使用另外
一种方式来调用man和woman中的study函数即:super().study();前面两种我们已经注释掉了我们只研究最后一种;即出现了上面的代码;那么这段代码会
出现什么呢?(反正我一开始觉得super()不是调用父类的方法嘛,既然son有两个父类,两个父类的study函数一起调用了呗,可是结果呢)

 代码执行结果:

我是儿子我要好好学习
我要学好化学和物理
我要学好数学

 噫噫噫,不对啊,和我想的不一样啊,只返回了man类中的方法;没有返回woman类中的方法啊;这是什么情况呢?一百的问号????

于是查看了很多的博客,毕竟还是有很多大神的嘛我们要向前辈们学习啊,于是对super()又有了新的认识:我们返回文章的第一句话,super()是个什么鬼?从新解释一下:super()不是一个函数而是一个类,super()相当于这个类调用了自己的初始化函数,返回了一个对象;这个对象是干嘛的呢,用来调用实例化对象中的mro()序列中的下一个  的  类的指定的类中的方法(mro()返回的是一个:方法解析顺序列表)估计又懵了,那么我们先打印一下:son.mro()

[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]

实际上打印出来的就是son的继承父类的顺序(son---man---woman---Person---object)

那么以本例来说在son中写了super(),那么son的下一个mro当然就是man类,所以就返回了man类中的study方法了。这就是上面那个疑问的解答了;那么问题又来了如果我在man类中也写了super().study(),那么接下来会打印什么呢?无非就两个可能一个是打印Person中的sutdy方法另一个可能就是打印woman类中的study方法(为什么是这两种呢,如果我们是以son为出发点man的下一个mro当然是woman;但是我们现在是把super().study()写在了man类中这个时候好像以man类为出发点也说的过去啊,那么我们先打印一下man,mro()。)

class man(Person):
    def __init__(self):
        print("我是男人我要好好学习")

    def study(self):
        print("我要学好数学")
        super().study()

结果:
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]

 果然man的下一个mro是Person而不是woman啊,如果我们执行上面的代码最终到底是打印person呢还是woman呢?看结果:

我是儿子我要好好学习
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要学好化学和物理
我要学好数学
我要学好英语

 打印出来的是我要学好英语是woman中的(而不是person中的);如果我们在woman类中也一起写上super(),那么:

class Person(object):
    def __init__(self):
        print("我要好好学习")

    def study(self):
        print("我要学好语言")


class man(Person):
    def __init__(self):
        print("我是男人我要好好学习")

    def study(self):
        print("我要学好数学")
        super().study()


class woman(Person):
    def __init__(self):
        print("我是女人我要好好学习")

    def study(self):
        print("我要学好英语")
        super().study()

class son(man,woman):
    def __init__(self):
        print("我是儿子我要好好学习")

    def study(self):
        print("我要学好化学和物理")
        # woman.study(self)
        # man.study(self)

        super().study()

    # def study1(self):
    #     print("我要学好英语")


son1 = son()
print(son.mro())
print(man.mro())
son1.study()
# son1.study1()

 结果:

我是儿子我要好好学习
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要学好化学和物理
我要学好数学
我要学好英语
我要学好语言

 看一下结果就知道了先打印了man类中的study方法,之后打印了woman类中的方法;最后打印了Person类中的study方法;所以到这里暂时得到一个结论:super()不是指父类(对于man类来说Person应该是父类)而只指以实例化对象为起点的mro序列中的下一个。

那么我们把上面的代码再来改一改,如果我把man类中的super()注释掉了,但是woman类中保留着super()会又什么样的的结果呢:

class Person(object):
    def __init__(self):
        print("我要好好学习")

    def study(self):
        print("我要学好语言")


class man(Person):
    def __init__(self):
        print("我是男人我要好好学习")

    def study(self):
        print("我要学好数学")
        # super().study()

class woman(Person):
    def __init__(self):
        print("我是女人我要好好学习")

    def study(self):
        print("我要学好英语")
        super().study()

class son(man,woman):
    def __init__(self):
        print("我是儿子我要好好学习")

    def study(self):
        print("我要学好化学和物理")
        # woman.study(self)
        # man.study(self)

        super().study()

    # def study1(self):
    #     print("我要学好英语")


son1 = son()

print(son.mro())
print(man.mro())

son1.study()


# son1.study1()

 结果:

我是儿子我要好好学习
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要学好化学和物理
我要学好数学

 结果是man类中的sutdy方法打印出来了然而woman和Person类中的study方法没有打印出来;相当与 son--man--woman中在man这里打断了,然后后面的也就不执行了。

好吧就到这里吧由于刚开始学习python,对于super()理解的还有很多不到位的地方;以后这篇文章还需要改进,暂时理解到这个程度。

猜你喜欢

转载自www.cnblogs.com/yan-peng/p/9961384.html