继承的爱恨情仇——一场钻石引发的血案

最近在看PHP手册,发现了一个稀奇古怪的新玩意——trait

这引起了我极大的兴趣,由于PHP面向对象的部分有很大程度和Java类似,我就自觉不自觉地和Java对比着来看。

这又让我想起了那个古老的故事——单继承和多继承。


说到这个问题,我最先想起的应该是C++和Java

图片来源:
编程语言拟人化(1):Java、C++、Python、Ruby、PHP、C#、JS
趣文:编程语言拟人化(第二弹)
這系列文章的原始出處,是日本的「リクナビ NEXT」這家日本的人力公司的《Java、C++、Python…プログラミング言語擬人化計画! 》和《Perl、C、Scala…プログラミング言語擬人化計画 2》;他基本上是針對幾種常見的程式語言去設計了萌化的腳色、以及根據該語言發展歷史的人設。

知乎用户:shawn sharp
链接:https://www.zhihu.com/question/25038841/answer/44433042
间接来源:知乎

众所周知,C++是个御姐,Java是个萝莉....啊不对....C++支持多继承而Java不支持

咋一看,觉得可能是Java做对了,C++的是落后粗野的方法。可是真的是这样吗?

难道多继承真的一无是处,百害而无一利吗?

显然不是这样的,当我们要用多继承时,我们期待的到底是什么效果呢?

我们期待的是:可以直接拿来用的类成员函数(方法)。这很重要吗?对很重要,因为这正是代码复用所在。

可说到代码复用首先想到的应该是普通函数,它不行吗?不行。像是Java这样的语言他本来就不支持普通函数,再者也是更重要的,我们要类成员函数的意义在于他有面向对象的一系列“红利”,这才是我们关心的,比如:覆盖、访问控制、多态等等,所以这些特性是普通函数所无法替代的也是我们迫切所需的。

当然,得到了这些“红利”的同时,我们往往也在被“喂屎”,最著名的便是“钻石继承”问题。

图片来自维基百科:Multiple inheritance

钻石继承当然有很多弊端,最常见的便是当B和C同时继承自A,然后D又继承了B和C。那假设B和C中都有一个成员函数x(),那么在D中这个x()函数将会用谁的版本呢?B的?还是C的?还有就是,假设A有一个成员变量y,它的构造函数会初始化它,那在D的构造函数执行的时候,它要初始化几个y呢,在D中的y又是哪一个呢?

这一系列问题看着就让人头大...恩,事实是C++居然都能有相应对策(不得不说,御姐赛高)。可是真的是心累啊...谁想整天处理这些鬼东西!人类之所以强大在于把复杂的问题简化而解决之,而不是愣头去啃复杂问题!

所以这个时候,trait就来了!

真的没有一种既能享受面向对象“红利”,又不用解决这么令人掉头发的复杂问题的东西吗?!当然有啦!它就是trait。

那trait究竟是个什么东西呢?抛去具体语法不谈,trait就是一个没有构造函数,不能被实例化的抽象类。哦...那问题不是还没被解决吗?!这不还跟原来一个样吗!

其实一开始我也很疑惑,这家伙到底和抽象类有啥区别!其实啊,还真没啥,就一个重大区别,那就是:在遇到冲突时,它能指定到底用哪个版本的成员函数。恩?什么意思?

就像我上文提到的那个问题,在B和C中分别有一个x(),在D中就发生了冲突,不知道该用哪个版本了。trait能指定,现在,在D中,我们用哪个x(),并且!没有被指定的那个,就像是暂时被舍弃了,就像不存在一样。所以,这是关键,这就是比C++进步的地方,C++也能指定用那个版本,但是未被指定的那个也还是在的。只有未被指定的被舍弃,才能从根本上解决二义性问题。

这样我们就能好好地享用“红利”而不再担心被“喂屎”了!

语言的发展的过程就是博弈的过程,就是取舍的过程啊!至少在这一点上,看来是这样的。

最后附上一张PHP的,出处同上

原文地址:https://www.cnblogs.com/joenahm/p/9127434.html

时间: 2024-11-25 05:02:32

继承的爱恨情仇——一场钻石引发的血案的相关文章

重新认识java(四) — 组合、聚合与继承的爱恨情仇

有人学了继承,认为他是面向对象特点之一,就在所有能用到继承的地方使用继承,而不考虑究竟该不该使用,无疑,这是错误的.那么,究竟该如何使用继承呢? java中类与类之间的关系 大部分的初学者只知道java中两个类之间可以是继承与被继承的关系,可是事实上,类之间的关系大体上存在五种-继承(实现).依赖.关联.聚合.组合. 接下来,简单的分析一下这些关系. 继承(实现) 对于类来说,这种关系叫做继承,对于接口来说,这种关系叫做实现.继承上一篇文章已经详细的讲解过了,至于实现,我想大家也都知道是怎么回事

js 爱恨情仇说 this

原文:js 爱恨情仇说 this this 相信大家在写代码的时候都会遇到,可是怎么样才能用好this,估计这个还是有点困难的,虽然你有时候你会用到,但是他所在的具体的几个场景中所代表的是什么意思了?可能这个你就不是很清楚啊.这个就会在你使用的过程中出现很多的问题,于是今天我们来总结一下this,到底这个this?他真的有想象中的那么难吗? 其实可以总结为一句话:this指的是调用函数的那个对象 于是我们可以总结出this的四个调用场景: (1) 方法模式:简单的说就是使用点表达式或是下标表达式

产品经理和程序员的爱恨情仇

产品经理跪求程序员,程序员跪求程序成功上线! 前几天纯银V在微博上发了一条微博「很多人吐槽“人人都是产品经理”这句话,其实在我看来,这句话的正确理解是“人人都应该学习产品经理的思维方式,来提升自己的专业能力”,不知道作者是否本意如此.当然,实际上它容易被理解为“我也可以做产品经理,创造一个伟大的产品”,那就很扯淡了.尤其水货产品经理的破坏力之强令人惊叹」,引发了诸多讨论. 我看了之后,意味深长的转发了一下:从来没人说人人都是程序员,这其实说明了一些什么……于是又引发了一番热议,比如: 对呀,也不

初识angular.js之爱恨情仇

angular.js Angular.JS 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它支持整个开发进程,提供web应用的架构,无需进行手工DOM操作. AngularJS很小,只有60K,兼容主流浏览器,与 jQuery 配合良好. 简单概括:MV*模型的js框架 angular.js之爱恨情仇 爱恋之际 MV*模式 职责清晰.层次分明,例如页面样式变化仅改变View代码,其它层次结构代码无需改动. 数据绑定 数据视图绑定(单.双向数据绑定),无需反锁的改变DOM的值或修

Menu与ActionBar的爱恨情仇

最近在开发一款音乐播放器,在开发过程中遇到了一点小麻烦,通过android API搞清楚了Menu与ActionBar的爱恨情仇,写了个小Demo祭奠一下那些年我们陷进去的坑,有不对的地方请大神们批评指正. 一.Android系统里的菜单接口(即Menu接口),它是一个父接口,其下又有两个子接口:SubMenu(子菜单)与ContextMenu(上下文菜单) 常用的菜单有以下三类:Option Menu(选项菜单,常与ActionBar连用),Context Menue(上下文菜单),Popup

web移动端fixed布局和input等表单的爱恨情仇 - 终极BUG,完美解决

[问题]移动端开发,ios下当fixed属性和输入框input(这里不限于input,只要可以调用移动端输入法的都包括,如:textarea.HTML5中contenteditable等),同时存在的时候:两位大侠瞬间发生剧烈的化学反应,出现各种奇葩问题,见下图: [结论]输入框position属性值不是fixed,而变成了absolute [出现情况]当我们唤起键盘的时候,输入框位置不再页面最下面,或者说页面当时还可以继续往下滚动,再或者页面没有滚动到最下边,这个时候就会出现上面的问题 [学习

那些年苹果与 USB 的爱恨情仇

喜新厌旧,人之常情,也是大公司常态. 大公司见异思迁的背后,往往都由利益推动.即使是一个小小的接口,背后都是博弈.像苹果这么傲娇的公司,更是把和USB接口的爱恨情仇演绎得淋漓尽致. 当年,他们曾经是在一起的. 最初Mac和搭载Windows PC的共同接口很少.比如,PC上打印机的接口是并行接口,鼠标和键盘接口是PS/2接口:Mac上的硬盘接口是SCSI接口,鼠标和键盘接口是ADB接口.即使是在调制解调器和外设接口方面,双方都是用的不同接口. 当时的Mac濒临死亡,完全不占优.1998年苹果推出

永和和红薯不得不说的爱恨情仇!

在 2014 年 12 月 24 日这一天下午,@叶秀兰童鞋无意中吐槽了一下自己的毁容事迹,结果,引发出了永和和红薯之间的爱恨情仇,OSCer 们实在是太有才,请慢慢欣赏,如有遗漏,请@小小编辑  告知一二,补上! @叶秀兰:最近毁容部分已经结痂.中午吃完饭,@永和   童鞋不经意的说了一句,你嘴没擦干净... @纠结名字 :@永和  心里想:终于有机会表现了,我要帮她擦嘴.但@叶秀兰  内心一紧,心想:毁容的事被他发现了!眉头一皱,大喊:走开! @chameleon :@永和  恁的一惊,这女

对json的爱恨情仇

本文回想了对json的爱恨情仇. C++有风险,使用需慎重. 本文相关代码在:http://download.csdn.net/detail/baihacker/7862785 当中的測试数据不在里面,由于这是项目开发中用到的,须要保密. 在工作时才接触json,看过简单介绍,语法简单,易于扩展,用起来是非常爽的事.和后端的一些交互也基本上都是用的json.在项目中用了第三方库:simple json,用起来也不亦乐乎.只是也吃过该库的亏: 1.忘了解析后的JSONValue应该delete掉;