2013-06-01 27 views
7

人們說C++繼承是邪惡的,所以Java用接口「固定」了這個問題。Scala mixin真的比多個C++繼承更好嗎?

但斯卡拉引入trait s,他們是...接口與部分實現?這不會帶來多重繼承嗎?

這是否意味着斯卡拉人認爲多重繼承是好的?或者他們有一些關鍵的區別,我沒有注意到?

+6

請看看[Programming in Scala](http://www.artima.com/pins1ed/traits.html#12.6)第258頁第12.6節。我發現這個解釋非常好,可能會嘗試重寫它,但我不會 - 寫出比這更全面的東西很難。總之,在斯卡拉沒有所謂的[*鑽石問題*](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem)(存在於C++中,這就是爲什麼C++多繼承嚴重受到批評) ,因爲缺少構造函數,定義好的方法調用順序和* super *的不同概念。 –

回答

8

多重繼承最糟糕的部分是菱形繼承,其中一個子類有兩個或更多路徑到同一個父級上的某個位置。如果實現沿着兩條路徑不同(即從原始實現被覆蓋),則這會造成不明確性。在C++中,解決方案特別難看:您嵌入了兩個不兼容的父類,並且必須指定何時調用您想要的實現。這是令人困惑的,在每個呼叫站點創建額外的工作(或者,更可能的是,迫使你明確地覆蓋並陳述你想要的;這個手工工作是乏味的並且引入錯誤的機會),並且可能導致對象大於他們應該是。

Scala通過限制多重繼承性狀解決了一些問題,但不是全部問題。因爲特徵沒有構造函數,所以最終類可以將繼承樹線性化,也就是說,儘管名義上返回到共同超父母的路徑上的兩個父母都是父母,但是一個是「正確」的,即最後列出的那個。如果你可以擁有(完全通用的)構造函數,這個方案會留下破壞的半初始化類,但實際上,你不需要兩次嵌入類,並且在使用的站點上,你可以忽略有多少繼承發生了。然而,它並沒有讓你更容易推斷當你將很多特質疊加在一起時會發生什麼,如果你繼承BC,你不能選擇B的實現和一些C的。

因此它更好地解決了一些對C++模型最嚴重的批評。是否足夠好是品味的問題;很多人甚至都喜歡C++多重繼承的味道,足以使用它。

+0

我寧願明確地指定不明確的成員,而不是依賴做出非顯而易見的選擇的規則。 – nclark

+0

@joeytwiddle - 我剛剛注意到你在一年半前發現了我的錯誤!修正了文字。 –

+0

@nclark - 除非你已經重寫,否則你不會得到非顯而易見的選擇,所以對非顯而易見的選擇有一些保護。但是,一旦你已經在兩個分支超負荷,是的,列出的最後一個是自動選擇的,並且有人可能會認爲,那麼明確的會更好。 (如果只是指定你想要的超類實現。) –