2011-11-09 38 views
12

我開始與斯卡拉,我發現這有點奇怪。在java中我可以做這樣的事情:爲什麼不擴展其他類的類必須擴展特性? (與不工作)

interface Foo{} 

public class Bar implements Foo{} 

我試圖做斯卡拉類似的東西,但它不工作:

trait Foo; 
class Bar with Foo; // This doesn't work! 

我必須使用「擴展」的關鍵字:

class Bar extends Foo; // This works OK! 

現在,這很好,但它不是我想要的。

奇怪我注意的是,鑑於斯卡拉每一個類從AnyRef擴展(請參閱從scala-lang.org這一形象:http://www.scala-lang.org/sites/default/files/images/classhierarchy.png)另一件事我可以做到這一點:

class Bar extends AnyRef with Foo; // This works too! 

所以,我失去了什麼?如果不擴展它,沒有意義使用特質?

謝謝!

回答

21

首先要注意的是,擴展/實現差異告訴沒什麼編譯器比它不知道。我並不是說它不好,只是語言本來可以做到的。在C#中,您編寫了class A : B, C, D而不是class A extends B implements C, Dclass A implements B, C, D。所以你可以認爲斯卡拉的extends就像冒號和with就像逗號一樣。

然而,在過去,它曾經是class Bar with Foo。當Scala在2006年回到2.0時,它發生了變化。請參閱the change history

我想我記得(不確定),原因很簡單,class Bar with Foo不好讀。

在斯卡拉,A with B是類型AB的交集。如果對象類型爲AB,則該對象的類型爲A with B。所以class A extends B with C可能會被讀取class A擴展類型B with C。沒有這樣的事情與class A with B

+0

很好的解釋,謝謝! – santiagobasulto

3

Programming in Scala (2nd ed)討論了在第12章它注意到與問候性狀extends

您可以使用extends關鍵字的特質混合;在這種情況下,你隱含地繼承了特徵的超類。例如,在清單12.2中,類 Frog的子類AnyRefPhilosophical的超類)和 Philosophical中的混合。

(在這裏,Philosophical是一個特點。)

所以,你的推理是完全正確的。

關於AnyRef的問題,您應該閱讀關於Scala class hierarchytop types。 (AnyRef不是頂級類型,但它是非常接近的。)

+0

我有那本書!我爲什麼想念它?謝謝@Emil – santiagobasulto

8

如果你來自Java,它聽起來可能聽起來很奇怪(我對它也一樣),但實際上現在我發現它是更規則的語法Java的,我需要明確說明我是想要implement還是extend其他類/接口。但我認爲這更多是個人品味的問題。

實際上你是否在說extendsimplements。它們代表了兩件事物之間的同一種關係:(與委託和組成相反,它們代表具有的關係)。在這裏,比如,你可以找到一些關於它的更多信息:

http://www.javacamp.org/moreclasses/oop/oop5.html

只是嘗試更換extendsimplementswithis a,變得更加清晰。

在斯卡拉你也有is a關係的其他變化。例如自我類型

trait Bar { 
    self: Foo => 
    // ... 
} 

有了這個,你都這麼說,那Bar不繼承/實現Foo直接,但所有其他類,希望延長Bar還應該擴展Foo

自我類型可以允許有趣的事情。例如兩類/依賴於彼此性狀:

class Bar extends Foo { 
    def sayHello(name: String) = println("Hello, " + name) 

    greet() 
} 

trait Foo { 
    this: Bar => 

    def greet() = sayHello("User") 
} 

new Bar() // prints: Hello, User 
+0

另請參閱http://www.levinotik.com/2012/09/14/scala-abstract-classes-traits-and-self-types/ – ZiglioUK

+0

這是一個有趣的答案,尤其是「自我類型」部分。謝謝! – asgs