~~核心编程(五):面向对象——多继承~~

进击のpython

*****

多继承


多继承?什么是多继承?就是继承多个呗!

这多好理解啊!

怎么叫多继承呢?

孙悟空知道吧!

猴子吧!神仙吧!

强行操作是不是就是两个父类!

那怎么继承?

你一个都会,两个就不会了??

对吧,要学会类比啊!

# -*- coding: utf-8 -*-
# @Time    : 2019.07.16
# @Author  : 爪爪
# @Url     : https://www.cnblogs.com/jevious/

class Shenxian:
    print("我是神仙,法力无边!")
    pass


class Monkey:
    print("我是猴子,我贼流弊!")
    pass


class Sunwukong(Monkey, Shenxian):
    pass

Sunwukong()
我是神仙,法力无边!
我是猴子,我贼流弊!

这时候你就可以发现,我sunwukong这个类

就继承了shenxian和monkey的属性

当然,sunwukong也可以继承他们的方法

# -*- coding: utf-8 -*-
# @Time    : 2019.07.17
# @Author  : 爪爪
# @Url     : https://www.cnblogs.com/jevious/

class Shenxian:
    def shen(self):
        print("我是神仙,法力无边!")
        pass


class Monkey:
    def hou(self):
        print('我是猴子,我贼流弊!')
        pass


class Sunwukong(Shenxian, Monkey):
    def sun(self):
        print("齐!天!大!圣!")
        pass


s = Sunwukong()

看,当我实例化之后调用方法的时候

来自父类的函数是不是也可以被调用


  • 继承顺序

    看着很简单哈,但是不仅仅是这样的哦

    你看啊,houzi是不是还可以继承个动物类?

    动物类是不是还可以继承生物类?

    生物类是不是还可以继承……

    总之如果要是拓展来说有好多对吧!

    在研究这个问题之前

    是不是还应该有个问题没被解决呢?

    就是要是我shenxian类和monkey类里

    都有个eat方法,当我sunwukong调用的时候

    是用哪个?

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Shenxian:
        def shen(self):
            print("我是神仙,法力无边!")
            pass
    
        def eat(self):
            print("神仙吃东西!")
    
    
    class Monkey:
        def hou(self):
            print('我是猴子,我贼流弊!')
            pass
    
        def eat(self):
            print("猴子吃东西!")
    
    
    class Sunwukong(Shenxian, Monkey):
        def sun(self):
            print("齐!天!大!圣!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    
    

    从提示可以看出来实例化的eat方法是来自shenxian的

    那到底是不是呢?

    执行一下!

    神仙吃东西!
    

    果然,执行的是shenxian里面的eat方法

    所以说大概就有概念了,这个继承啊

    是有顺序的

    先继承shenxian里面的方法,再继承monkey的方法

    重复的以前面的为准(shenxian在monkey前面)

    但是,你以为

    这就完事了?


    就像我刚才提到的那个问题

    如果是那种情况,继承顺序是什么样的呢?????

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Super_shenxian:
        def eat(self):
            print("超级神仙吃东西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def shen(self):
            print("我是神仙,法力无边!")
            pass
    
        def eat(self):
            print("神仙吃东西!")
    
    
    class Shengwu:
        def eat(self):
            print("生物吃东西")
    
        pass
    
    
    class Monkey(Shengwu):
        def hou(self):
            print('我是猴子,我贼流弊!')
            pass
    
        def eat(self):
            print("猴子吃东西!")
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齐!天!大!圣!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    

    在执行之前,我们先来分析一下这个程序的继承关系

    是吧,是这样的吧!没问题吧

    那按照我们来想的

    是不是应该可以有两种查找方法

    sunwukong⇨monkey⇨shengwu⇨shenxian⇨super_shenxian

    这种查找方法叫 深度优先

    sunwukong⇨monkey⇨shenxian⇨shengwu⇨super_shenxian

    这种查找方法叫 广度优先

    那我们的继承遵循哪种呢?

    执行上方代码

    猴子吃东西!
    

    但是这也不能确定是深度还是广度

    那如果shengwu有eat方法

    shenxian也有eat方法

    但是monkey没有eat方法

    那我要是执行结果是“神仙吃东西”

    是不是就代表着是广度优先?

    同理,我要是执行结果是“生物吃东西”

    是不是就代表着是深度优先?

    这个逻辑能理解吧

    那我们试一下

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Super_shenxian:
        def eat(self):
            print("超级神仙吃东西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def shen(self):
            print("我是神仙,法力无边!")
            pass
    
        def eat(self):
            print("神仙吃东西!")
    
    
    class Shengwu:
        def eat(self):
            print("生物吃东西")
    
        pass
    
    
    class Monkey(Shengwu):
        def hou(self):
            print('我是猴子,我贼流弊!')
            pass
    
        # def eat(self):
        #     print("猴子吃东西!")
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齐!天!大!圣!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    
    

    执行结果是:

    生物吃东西
    

    那说明什么?说明继承是深度优先是吧!

    逻辑没问题吧!

    你以为???这就结束了???


  • 真◇继承顺序

    在python中啊,类的写法有两种

    经典类:

    class A:
        pass
    

    新式类:

    class B(object):
        pass
    

    而python呢,又有两种版本 2.x 和 3.x

    所以就出现了四种组合情况是吧!

    在2.x版本中,经典类采用的是深度优先,新式类采用的是广度优先

    在3.x版本中,无论新式类还是经典类,都是按广度优先查找的

    在2.x中默认的都是经典类,只有显示继承了object才是新式类

    在3.x中默认的都是新式类,不必显示继承object

    等会???????????????

    刚才咱们实验出来了,3.x版本是深度优先啊!

    怎么你现在跟我说是广度优先???????

    kidding me???????????????

    别骂人别骂人!听我狡辩说啊!


    有没有这种情况?

    我的super_shenxian 和 shengwu 的上面还有个爹

    shijie!

    可以不!

    shijie里面也有eat方法行不

    我把houzi的eat取消掉

    我再把shengwu的eat取消掉

    那我查找的时候是不是应该继续找shengwu的父亲

    也就是shijie!

    然后执行shijie里面的eat是吧

    最后打印”世界吃东西“是吧

    这是咱们原先的逻辑,没问题吧!

    写一下行吧

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Shijie(object):
        def eat(self):
            print("世界都在吃东西!")
    
        pass
    
    
    class Super_shenxian(Shijie):
        def eat(self):
            print("超级神仙吃东西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def eat(self):
            print("神仙吃东西!")
    
    
    class Shengwu(Shijie):
        # def eat(self):
        #     print("生物吃东西")
    
        pass
    
    
    class Monkey(Shengwu):
        # def eat(self):
        #     print("猴子吃东西!")
        pass
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齐!天!大!圣!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    
    

    你打印出来的是什么??大声告诉我!

    是不是”世界吃东西“?

    不是!

    是什么?

    神仙吃东西!

    是不是就不是深度优先原则了????

    那他到底是什么优先呢???????

    其实好多都在说是广度优先

    但是很明显,当没有交集的时候,依照的是的是深度优先

    有交集又用的是类广度有限的算法

    那到底是什么!!!!!!!!!!!!!


  • 多继承C3算法

    上面的都算简单的,来来来,看看这个?

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class A:
        def test(self):
            print('from A')
    
    
    class B(A):
        # def test(self):
        #     print('from B')
        pass
    
    
    class B2:
        def test(self):
            print('from B2')
    
    
    class C(A):
        def test(self):
            print('from C')
    
    
    class C2:
        def test(self):
            print('from C2')
    
    
    class D(B, B2):
        # def test(self):
        #     print('from D')
        pass
    
    
    class E(C, C2):
        def test(self):
            print('from E')
    
    
    class F(D, E):
        # def test(self):
        #     print('from F')
        pass
    
    
    f1 = F()
    f1.test()
    

    输出结果自己打印┗|`O′|┛ 嗷~~

    那这个继承关系是什么呢????

    来,我的好兄弟

    告诉我,tell me

    这是什么顺序???

    广度???

    深度???

    其实都不是,这是一个叫C3算法来计算继承顺序的

    不打算说,因为我也不会

    所以你要是想研究

    你就去难为百度去,行不?

    那我就想知道继承顺序怎么办??

    好说,程序员都给你写出来方法了

    print(F.__mro__)  # 打印类的继承顺序
    

    你打印出来的就是继承顺序!

    (<class '__main__.F'>, 
     <class '__main__.D'>, 
     <class '__main__.B'>,
     <class '__main__.E'>, 
     <class '__main__.C'>, 
     <class '__main__.A'>, 
     <class '__main__.B2'>, 
     <class '__main__.C2'>, 
     <class 'object'>)
    

    都有方法了,你还自己找???

    那你可真是个小机灵!

    其实这都是很极端的

    真正写的哪有这么继承的?

    顶多就写到shijie那种就可以了

    写成这样的

    不是天才,就是疯子!


*三大特性之一*
*你不会能行吗*
原文地址:https://www.cnblogs.com/jevious/p/11200457.html