博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
继承的爱恨情仇——一场钻石引发的血案
阅读量:4664 次
发布时间:2019-06-09

本文共 1499 字,大约阅读时间需要 4 分钟。

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

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

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

 

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

图片来源:
這系列文章的原始出處,是日本的「リクナビ NEXT」這家日本的人力公司的《 》和《》;他基本上是針對幾種常見的程式語言去設計了萌化的腳色、以及根據該語言發展歷史的人設。
知乎用户:shawn sharp
链接:https://www.zhihu.com/question/25038841/answer/44433042
间接来源:知乎

 

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

 

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

 

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

 

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

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

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

 

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

 

图片来自维基百科:

 

钻石继承当然有很多弊端,最常见的便是当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

你可能感兴趣的文章
mysql中 key 、primary key 、unique key 和 index 有什么不同
查看>>
java 多线程笔记
查看>>
C#中的委托(Delegates in C#)- part two
查看>>
JDBC中级篇(MYSQL)——处理文件(BLOB)
查看>>
jabRef里引用的相邻同名作者变横线
查看>>
【洛谷 2888】牛栏
查看>>
Java PDF页面设置——页面大小、页边距、纸张方向、页面旋转
查看>>
Spring AOP 的实现机制
查看>>
74.VS2013和opencv3.1.0安装教程
查看>>
doviceone- http组件进行webservice的POST请求
查看>>
Killer Problem (UVA 11898 )
查看>>
MVC模式在Java web应用程序中的实现
查看>>
五种开源协议的比较
查看>>
递推和递归Number Sequence
查看>>
一.多线程技能
查看>>
Nginx 常用命令总结
查看>>
hall wrong behavior
查看>>
Markdown test
查看>>
Collection集合
查看>>
int最大值+1为什么是-2147483648最小值-1为什么是2147483647
查看>>