若用多重继承 一定要考虑mix-in混合类
为什么要用mix-in混合类
Python是面向对象的编程语言,它提供了一些内置的编程机制,使得开发者可以适当地实现多重继承,即一个子类可以继承多个父类,但是多重继承的设计经常被人诟病,因为它违背了“is-a”的关系。但是也存在需要多重继承的情况。
例如,轿车是一个交通工具,所以轿车类应该继承交通工具这个父类。那民航飞机呢?它也属于交通工具的一种,所以也应该继承交通工具这个父类,但是交通工具这个类应该怎么设计?是否应该实现飞行功能?如果实现,那轿车继承交通工具父类显然不合适,因为轿车根本没有飞行功能。如果不实现,民航飞机继承交通工具类也同样不合适。如果两者都分别实现自己的方法,那将会违背代码重用的原则,那应该这么解决这个问题?事实上,我们可以把地上跑的,天上飞的,甚至水上漂的这些工具的功能抽象出来实现交通工具这个父类。对于飞机来说,那就去继承交通工具和有飞行功能两个父类,对于船来说,那就去继承交通工具和有水上漂功能的两个父类。但是这样子的多重继承说到底还是违背了“is-a”的原则,这个问题应该怎么样处理?
其实在Python里,是可以这样子处理的,看示例1。
#示例1 class Vehicle(object): def move(self): print("I can move on the road") class FlyMixin(object): def fly(self): print("I can fly in the sky") class Airplane(Vehicle, FlyMixin): pass
在示例1中,Airplane继承了Vehicle和PlaneMixin两个类,这是多重继承吗?其实可以说是,也可以说不是。因为从语法上来说,的确是多重继承。不过要注意的是Airplane第二个继承的是类名称有“mixin”,说明这是一个混合类(mix-in类),它会告诉读代码的人,这个FlyMixin类只是起到一个辅佐作用,它只是把某一个功能添加到类中,即使没有继承这个FlyMixin类也没有影响。mix-in是一个小型的类,它只是定义了其他类可能需要的一套附加方法,而不定义自己实例属性,此外,它也不要求使用者调用自己的构造器。
了解完mix-in类,我们一起来看看示例2的例子。
#示例2 class Animal(object): def run(self): print("I can run!") def eat(self): print("I can eat!") def drink(self): print("I can drink") def sleep(self): print("I can sleep") class AnimalMixin(object): def maketools(self): print("I can make tools!") class Person(Animal, AnimalMixin): def superpower(self): super().maketools() Jack = Person() Jack.superpower() #输出结果:I can make tools!
人和其他动物都具有run,eat,drink,sleep方法,但是人和其他动物的区别是人可以制造工具。所以我们在mix-in类中实现maketools方法,它用于给Person类添加一个额外功能我们在实现Person类的时候,继承了Animal父类和AnimalMixin混合类。继承的UML图如下图所示:
说到多重继承,不得不说一下方法顺序解释(MRO),当子类调用super()放时候,它指明了查找方法的顺序。
print(Person.__mro__) #输出结果: # (<class '__main__.Person'>, <class '__main__.Animal'>, <class '__main__.AnimalMixin'>, <class 'object'>)
super()查找顺序如下图所示(虚线)。
混合类应该要注意
- 它应该表示某一种功能。
- 它必须负责单一的功能,如果需要多功能,请实现多个Mix-in类。
- 不依赖子类的实现。
- 子类即使没有实现Mix-in类,也可以正常工作,只是少了一个功能罢了。
公众号: CVpython
专注于分享Python和计算机视觉,我们坚持原创,不定期更新,希望我们的文章可以启发到你,一起进步。快点扫码关注我吧。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
手把手教你用Python画一个绝美土星环
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 导读:本文带你了解 Python 图形工具能够做哪些事情。 土星的行星环非常出名。虽然木星、土星、天王星和海王星也有环,但土星环是我们太阳系中最大、最亮、最广为人知的行星环。 它由小到灰尘的颗粒,大到巨石的物体组成。这些物体的成分主要是冰,一般认为是彗星或较大的小行星与土星的一颗卫星相撞时产生的,两者都撞成了小碎块。在远古时代,土星就已为人所知,但直到1610年,伽利略才首次用望远镜对它进行观测。 这个行星以罗马农业之神土星Saturn命名为,也就是我们每个星期的第六天Saturday。 图1至图5中的图像是由本文文末的代码生成的。每张图都呈现不同的方向角,图标题中有相应的说明。 图标题中还列出了入射光线的单位矢量分量,例如lx=+0.707,ly=+0.707,lz=0 表示左上象限中的光源;lx=-1,ly=0,lz=0表示来自右侧的光源。在图像中请注意行星在环上投射的阴影,尤其是在图5中能够看到行星轮廓的曲率。 我们对土星环也进行同样的操作。我们可以创建平行于XZ平面的水平环,然后...
- 下一篇
Dubbo分析之心跳设计
前言 谈到RPC肯定绕不开TCP通信,而主流的RPC框架都依赖于Netty等通信框架,这时候我们还要考虑是使用长连接还是短连接: 短连接:每次通信结束后关闭连接,下次通信需要重新创建连接;优点就是无需管理连接,无需保活连接; 长连接:每次通信结束不关闭连接,连接可以复用,保证了性能;缺点就是连接需要统一管理,并且需要保活; 主流的RPC框架都会追求性能选择使用长连接,所以如何保活连接就是一个重要的话题,也是本文的主题,下面会重点介绍一些保活策略; 为什么需要保活 上面介绍的长连接、短连接并不是TCP提供的功能,所以长连接是需要应用端自己来实现的,包括:连接的统一管理,如何保活等;如何保活之前我们了解一下为什么需要保活?主要原因是网络不是100%可靠的,我们创建好的连接可能由于网络原因导致连接已经不可用了,如果连接一直有消息往来,那么系统马上可以感知到连接断开;但是我们系统可能长时间没有消息来往,导致系统不能及时感知到连接不可用,也就是不能及时处理重连或者释放连接;常见的保活策略使用心跳机制由应用层来实现,还有网络层提供的TCP Keepalive保活探测机制; TCP Keepaliv...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块