~~核心编程(五):面向对象——多继承~~
进击の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那种就可以了
写成这样的
不是天才,就是疯子!