2012-06-30 23 views
6
scala> class A 
defined class A 

scala> class B {this: A => } 
defined class B 

scala> new B 
<console>:10: error: class B cannot be instantiated because it does not conform 
to its self-type B with A 
      new B 
      ^

B設置自類型A類,因此類B(或它的一個子類)具有延長A要創建的類B一個實例。但是,這完全可能,因爲B的子類只能擴展一個類(這是類B)?另一個類的自我類是否有意義?

所以這引出了我的問題,在任何情況下將類的自我類型聲明爲另一個類是否有意義?

回答

10

你的觀點是正確的,這個定義不能導致具體的實現,因爲你不能混合兩個類,只有特徵。所以簡短的答案是'不',或者應該是一個特質。

有關自我類型的Stackoverflow有幾個問題。兩個有用的是這些:

在第二個問題,有由本Lings一個很好的答案誰從Spiros Tzavellas博客中引用了下面這段話:

總之,如果我們想要在特徵內部移動方法實現,那麼我們冒着用抽象方法污染這些特徵的接口的風險支持實施具體方法,與特質的主要責任無關。解決這個問題的方法是將這些抽象方法移動到其他特徵中,並使用自我類型註釋和多重繼承來組合特徵。

例如,如果A(假設它是一個特質,而不是現在的類!)是一個記錄器。您不想公開B公開A混合的日誌API。因此,你會使用自我類型而不是混合。在B的實現中,您可以調用日誌API,但從外部看不到。


在另一方面,你可以在下面的表單中使用組成:

trait B { 
    protected def logger: A 
} 

現在的區別是,

  • B想使用它的功能時,必須參考logger
  • B的亞型可以訪問logger
  • BA不會在命名空間中競爭(例如,可能會對無碰撞

我要說的是,自類型是斯卡拉的相當外圍功能的同名方法),你不需要他們在很多情況下,你有這樣的選擇,以實現幾乎同樣沒有自我類型。

+0

很好的答案,非常感謝。 –

相關問題