python---之super()继承,解决钻石继承难题
1. Python的继承以及调用父类成员
python子类调用父类成员有2种方法,分别是普通方法和super方法
假设Base是基类
class Base(object):def __init__(self):print “Base init”
则普通方法如下
class Leaf(Base):def __init__(self):Base.__init__(self)print “Leaf init”
super方法如下
class Leaf(Base):def __init__(self):super(Leaf, self).__init__()print “Leaf init”
在上面的简单场景下,两种方法的效果一致:
>>> leaf = Leaf()
Base init
Leaf init
2. 钻石继承遇到的难题
当我们来到钻石继承场景时,我们就遇到了一个难题:
如果我们还是使用普通方法调用父类成员,代码如下:
class Base(object):def __init__(self):print “Base init”
class Medium1(Base):def __init__(self):Base.__init__(self)print “Medium1 init”
class Medium2(Base):def __init__(self):Base.__init__(self)print “Medium2 init”
class Leaf(Medium1, Medium2):def __init__(self):Medium1.__init__(self)Medium2.__init__(self)print “Leaf init”
当我们生成Leaf对象时,结果如下:
>>> leaf = Leaf()
Base init
Medium1 init
Base init
Medium2 init
Leaf init
可以看到Base被初始化了 两次 !这是由于Medium1和Medium2各自调用了Base的初始化函数导致的。
3. 各语言的解决方法
钻石继承中,父类被多次初始化是个非常难缠的问题,我们来看看其他各个语言是如何解决这个问题的:
3.1. C++
C++使用虚拟继承来解决钻石继承问题。
Medium1和Medium2虚拟继承Base。当生成Leaf对象时,Medium1和Medium2并不会自动调用虚拟基类Base的构造函数,而需要由Leaf的构造函数显式调用Base的构造函数。
3.2. Java
Java禁止使用多继承。
Java使用单继承+接口实现的方式来替代多继承,避免了钻石继承产生的各种问题。
3.3. Ruby
Ruby禁止使用多继承。
Ruby和Java一样只支持单继承,但它对多继承的替代方式和Java不同。Ruby使用Mixin的方式来替代,在当前类中mixin入其他模块,来做到代码的组装效果。
3.4. Python
Python和C++一样,支持多继承的语法。但Python的解决思路和C++完全不一样,Python是的用就是super
我们把第2章的钻石继承用super重写一下,看一下输出结果
class Base(object):def __init__(self):print “Base init”
class Medium1(Base):def __init__(self):super(Medium1, self).__init__()print “Medium1 init”
class Medium2(Base):def __init__(self):super(Medium2, self).__init__()print “Medium2 init”
class Leaf(Medium1, Medium2):def __init__(self):super(Leaf, self).__init__()print “Leaf init”
我们生成Leaf对象:
>>> leaf = Leaf()
Base init
Medium2 init
Medium1 init
Leaf init
可以看到整个初始化过程符合我们的预期,Base只被初始化了1次。而且重要的是,相比原来的普通写法,super方法并没有写额外的代码,也没有引入额外的概念
转载:https://www.tuicool.com/articles/eEzmmay
注:super()其实就是继承父类的方法,用了super相当于子类也可以调用父类的方法了
super()解决的就是钻石继承的难题
super().init()表示继承父类的初始化(并不代表其他方法也可以继承)
super().方法()表示继承父类的方法
super().init(**kwargs)其中的kwargs是初始化父类A 的__init__函数
python---之super()继承,解决钻石继承难题相关推荐
- 深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object):def __init__ ...
- python 钻石继承_python3--object类,继承与派生,super方法,钻石继承问题
python3--object类,继承与派生,super方法,钻石继承问题 发布时间:2018-04-13 20:38:05编辑:Run阅读(1914) 昨天内容复习 组合:什么有什么的关系(例:老师 ...
- c/c++入门教程 - 2.4.6 继承、公共继承、保护继承、私有继承、virtual虚继承(概念、语法、方式、构造和析构顺序、同名成员处理、继承同名静态成员处理、多继承语法、菱形继承、钻石继承)
目录 4.6 继承 4.6.1 继承的基本语法 4.6.2 继承方式 4.6.3 继承中的对象模型 4.6.4 继承中构造和析构顺序 4.6.5 继承同名成员处理方式 4.6.6 继承同名静态成员处理 ...
- 利用python画钻石_day25 python学习 继承,钻石继承
通过一个列子认识父类和子类中,子类的如何实现对父类默认属性调用,同时拥有自己的属性, 如何在子类中调用父类的方法, classAinmal: country='afdas' def __init__( ...
- day25 python学习 继承,钻石继承 多态
---恢复内容开始--- 通过一个列子认识父类和子类中,子类的如何实现对父类默认属性调用,同时拥有自己的属性,如何在子类中调用父类的方法,class Ainmal:country='afdas'def ...
- 车票?工作?对象?Python 教你优雅解决年关三大难题!
作者 | 数据不吹牛 最近,很多朋友都已经连续多日沉浸在即将(已经)放假的快感之中,化身渔夫,兢兢业业地摸鱼. 但是!你真的准备好过年了嘛!你真的知道为什么过年叫年关吗? 让小Z来给你讲个故事,从前, ...
- Python super钻石继承
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object):def __init__ ...
- Python super(钻石继承)
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object):def __init__ ...
- 利用python画钻石_python入门 -- 钻石继承(菱形继承)
在面向对象(OOP)编程中,很多情况下会遇到多继承和多重继承的问题和坑,这里带对大家 认识一下其中的一个钻石继承(菱形继承)的问题. 什么时候会出现钻石继承(菱形继承)呢? 当在类树中,由多个类共享同 ...
最新文章
- php定时执行代码漏洞_【漏洞风险提示】Drupal任意PHP代码执行漏洞通告
- XShell与虚拟机连接的IP问题
- Sublime Text 2 安装配置插件
- 无法识别的属性 configProtectionProvider的解决方案
- json里面返回模板输出的html,在JSON响应中返回完整页面的HTML而不是字符串输出...
- powerdesigner 导出数据库表结构
- python能和wincc一起用_搬家第二天-41.Wincc V7.3 利用Inputbox和Msgbox做权限管理和二次确认设计...
- 技巧收藏|10个JavaScript常用数组操作方法
- 函数名的使用-闭包-迭代器
- Python实现word转pdf
- SATA硬盘有固件问题的硬盘型号以及购买建议
- 教你如何选型到合适的OA系统
- c语言中分号作用,在C语言中逗号、分号等的用法
- 人类其实很脆弱,一个小小的条件变化,就能导致人没法享受元宇宙
- 国内外常用的即时通讯软件合辑
- 超级简单的 RocketMQ 流量削峰实战
- 基于RTL—SDR及Simulink的FM收音机仿真
- 网恋中在拿谁的情感玩游戏
- 山东省计算机应用能力等级考试,山东省2017年9月全国计算机等级考试报名时间...
- php 正则匹配小括号