开发区域

MATLAB高级软件开发

宽钻

有时候,Java®让我很烦。

不要误解我的意思,在许多方面,它是一种美丽的语言,充满了优雅的结构和所有您需要帮助驱动健壮的体系结构的工具。然而,另一方面,这种结构和严格的规则增加了层次的复杂性,并且需要平凡的、无趣的、失去激情的样板代码来完成您想要的接口,同时还要实现代码重用,以保持您的生产力。

另一方面,有时c++让我害怕。

c++更接近于金属,如果你不能一字不差地背出c++标准的每一部分,或者不能准确地知道每个编译器是如何实现标准的,那你就是搬起石头砸自己的脚。这太棒了,允许您完全访问和完全控制1和0的流位如何在硬件上跳舞,同时当这些相同的1和0崩溃和烧毁时,也会造成毁灭性的破坏。

比较这些方法的一个有趣的案例研究是著名的死亡钻石多重继承的问题。c++支持多重继承,由于默认的c++语义,当遇到多重继承时是非常危险的。以下面这个简单的菱形结构为例:

默认情况下,创建的底层c++对象实际上产生两个实例一个如下所示,每个继承路径对应一个。这可能会造成极大的痛苦,特别是在运行时进行强制转换,并且对象以不可预见和意想不到的方式被分割时。当A有两个真实值时,你也可以看到你如何进入不一致的状态,如果你通过指向B的指针改变一个属性,并通过指向C的指针访问该属性,你就实际上设置和访问该属性的两个不同副本!

现在,随着我们学习更多的c++,有避免这种歧义的方法但总的来说,我认为在c++中使用多重继承是一种充满危险的高级策略是合理的,为了避免掉进这些危险的陷阱,你最好完全和完全地知道你在做什么。由此产生的文化一直避免多重继承,这在很大程度上是由于钻石问题的这种行为。

事实上,这个问题已经对Java和c#等语言的设计产生了直接影响,因为它们特别禁止属性和方法的多重继承。当然,您可以实现许多接口,但这些接口不能有实现(是的,在Java 8中,现在有接口的默认方法,但它们不能包含任何可供这些方法操作的属性)。结果是大量的样板代码,其中Java对象实现了接口,但需要硬编码接口实现的链接到跨许多对象共享的一些实现。这个锅炉板代码有时会让我热血沸腾!好吧,我不是很生气,但听起来不错。我确实认为,无法从两个基类继承内容,导致代码数量远远超过实际需要,对我来说,代码是一种负担。

这个问题归结于缺乏语言特性。对死亡钻石继承结构的鄙视很大程度上是由于c++复杂/危险的语言语义,但是当我们使用一种更安全的语言处理它时,许多避免它的原因就消失了。例如,MATLAB以一种更加合理和可理解的方式处理多重继承。遇到菱形结构并不像在c++中那样严重,有时甚至可能完全没问题。例如,公共基类只存在一个实例(一个)和方法歧义被捕获和防止。

最后,我经常发现,在对这个问题进行深入讨论时,许多人将多重继承视为一种气味,不惜一切代价避免菱形结构。然而,当我们开始研究它们为什么这样做时,很难找到一个独立于特定语言(如c++)细节的答案。

我并不提倡匆忙地在代码中添加一堆菱形结构!实际上,它经常表明可能存在抽象问题,而且存在微妙之处(例如,共享基类只有一个实例,但MATLAB调用了它的构造函数两次)。然而,在MATLAB中,它更易于管理,最终适应菱形问题使您可以使用mixins。mixin的使用是一种强大的设计策略,它利用了多重继承,是一种替代方案作文这同样有帮助保持广泛的层次结构。我们下次再讲。

你怎么看?我遗漏了什么吗?你能帮助描述超越语言语义的钻石问题的基本问题吗?你是否曾有意或无意地在MATLAB中遇到钻石,如果有,它有什么影响?




MATLAB®R2015a发布

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。

Baidu
map