首页 > 数据库 > 数据库开发技术 > python面向对象编程篇(6):再说说继承问题
本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。
个人其他博客地址:
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
从前面的几篇介绍中可以知道面对对象的几个特性:
再一定的程度上其实可以理解为:我们有了封装---》才有了继承---》有了继承---》才派生出了多态。
继承解决的主要问题点:
在python里面我们的继承还有一个特性就是,它支持多继承,不像我们的java只支持单一的继承。
但是在python世界多继承的优缺其实主要是看你的应用场景而定,这里再有必要的说一下继承的问题,主要是多继承的问题容易引发,到底说是“真正的老爹”的问题。而且如果“多爸”包含一样的属性的时候,我该继承谁的问题也尤为关键。
首先我们还需要知道一个小知识点就是:在python定义类的实现的时候,不同的版本有不同的叫法,内部实现的调度顺序算法也是不一样。
多数情况下,基本我们的都是基于Py3的版本进行开发了,所以上面的分类其实没多大的影响,纯当补充额外的知识点。
多继承下方法调用的顺序:
我先继承谁的就是谁(如图 谁先摸到头我就调用谁的方法)
如新式类示例代码:
# -*- coding:utf-8 -*-
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen,MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
def say(self):
print("我是女孩子")
class HaiziRen_nan_nv(HaiziRen_nan, HaiziRen_nv):
pass
haizinannv= HaiziRen_nan_nv()
haizinannv.say()
输出的结果为:
我是男孩子
上面我的HaiziRen_nan_nv集成的是HaiziRen_nan()所以它调用的HaiziRen_nan的say方法。
如果反过来:
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen,MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
def say(self):
print("我是女孩子")
class HaiziRen_nan_nv(HaiziRen_nv, HaiziRen_nan):
pass
haizinannv= HaiziRen_nan_nv()
haizinannv.say()
则输出的结果为:
我是女孩子
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen,MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
def say(self):
print("我是女孩子")
class HaiziRen_nan_nv(HaiziRen_nv, HaiziRen_nan):
pass
def say(self):
print("是男是女,我说了才算!")
haizinannv= HaiziRen_nan_nv()
haizinannv.say()
输出的结果为:
是男是女,我说了才算!
如上面的4.2代码的示例示例:
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen,MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
def say(self):
print("我是女孩子")
class HaiziRen_nan_nv(HaiziRen_nv, HaiziRen_nan):
pass
def say(self):
print("是男是女,我说了才算!")
print(HaiziRen_nan_nv.mro())
输出的.mro()结果为:
[
<class '__main__.HaiziRen_nan_nv'>,
<class '__main__.HaiziRen_nv'>,
<class '__main__.HaiziRen_nan'>,
<class '__main__.BabaRen'>,
<class '__main__.MamaRen'>,
<class 'object'>
]
从上到下的顺序依次为:HaiziRen_nan_nv-->HaiziRen_nv-->HaiziRen_nan......
子承父业的时候:子调用相关属性和方法的时候,先从自己的字典里查询,如果没有,再根据我第一个优先继承的那个人去它的字典里面查,这就也就是说所谓的根据基类的线性顺序表去定位。
如:
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen, MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
pass
class HaiziRen_nan_nv(HaiziRen_nv, HaiziRen_nan):
pass
haizinannv = HaiziRen_nan_nv()
haizinannv.say()
输出的结果是:
我是男孩子
再两个都没有的情况,最终我只能找到HaiziRen_nan里面有:叫用它的方法了!
子承父业的时候:子属性和方法,不影响父类的属性和方法,各自独立更生:
子承父业的时候:子可以啃老(调用父类的属性和方法),老的不能吃子的,有点M憋屈的感觉(父类不能调用子类的属性和方法):
两个都是用于类型的判断,但主要区别在于:是否包含继承关系的判断。
type 不包含继承关系的判断
instance 包含继承关系的判断
class BabaRen():
def __init__(self):
pass
def say(self):
print("我是老爸")
class MamaRen():
def __init__(self):
pass
def say(self):
print("我是老妈")
class HaiziRen_nan(BabaRen, MamaRen):
def say(self):
print("我是男孩子")
class HaiziRen_nv(BabaRen, MamaRen):
pass
class HaiziRen_nan_nv(HaiziRen_nv, HaiziRen_nan):
pass
haizinannv = HaiziRen_nan_nv()
haizinannv.say()
print(isinstance(haizinannv,HaiziRen_nan_nv))
print(isinstance(haizinannv,HaiziRen_nan))
print("===========")
print(type(haizinannv) is HaiziRen_nan_nv)
print(type(haizinannv) is HaiziRen_nan)
输出的结果:
我是男孩子
True
True
===========
True
False
子承父业的继承模式,可以让子类瞬间拥有了父类的相关属性和方法。再结合多继承的情况,我们好像可以可以未为所欲为的组装我们的功能了。
逼的贝利亚奥特曼的进阶之路:

class Aote():
def __init__(self):
print("我是奥特之父")
class Dijia(Aote):
def __init__(self):
pass
print("我是---迪迦---奥特曼")
class Saiwen(Aote):
def __init__(self):
pass
print("我是---赛文---奥特曼")
class Jiguang():
def jineng_fashejiguang_1(self):
print("技能1:惯性冲击,借用从高空下冲的力量去撞击敌人,冲击时双手与大气摩擦产生强大的冲击力")
def jineng_fashejiguang_2(self):
print("技能2:冲击光拳,将能量聚集在手上,再使出全力打向敌人,威力惊人")
class DaoTou():
def dadaoyiba_1(self):
print("技能:奥特念力")
def dadaoyiba_2(self):
print("技能:头镖")
class Sgenjian():
def shenjian(self):
print("拥有一把削铁如泥的宝剑!!!!")
# 贝利亚奥特曼融合迪迦到特曼
class Beiliya(Dijia,Jiguang,DaoTou,Sgenjian):
pass
a = Beiliya()
a.jineng_fashejiguang_1()
a.jineng_fashejiguang_2()
a.shenjian()
贝利亚奥特曼融合了迪迦奥特曼还有组装上了其他技能!!!!然后变的超神了!!!
总结MixIn混入模式,可以多继承的方式,进行相关组合多个子类的功能的实现。
主要是为了框架便捷的快速的进行代码重用而设计的一种模式。通过这种模式扩展子类的功能,避免设计多层级的复杂的继承关系。有点类似吸星大法一样,看谁的技能强,就把它给吸收了就行!!!
纯属个人实践中相关经验阐述总结,如有纰漏,还希望大佬们多多提点!小钟同学 | 文 【原创】| QQ:308711822
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。