2017-04-21 75 views
1

讓我們有這樣的簡化代碼:類型成員的多壓倒一切

class Base { 
    self => 
    type Actual <: Base {type Actual = self.Actual} 

    def me: Actual = this.asInstanceOf[Actual] 
} 

class A extends Base { 
    override type Actual = A 
} 

class B extends A { 
    override type Actual = B 
} 

println((new B).me) 

我想me始終有一個正確的返回類型(流利的接口)。不幸的是這個代碼與崩潰:

test.scala:13: error: overriding type Actual in class A, which equals this.A; 
type Actual has incompatible type 
    override type Actual = B 
       ^
one error found 

如何實現期望的行爲,爲什麼它崩潰的第二種類型的成員覆蓋?

+0

你可以使用'self.type',而不是定義一個類型成員 –

回答

1

這通常通過f有界多態性來實現。

class Base[Actual <: Base[Actual]] { 
    def me: Actual 
} 

class A extends Base[A] 

class B extends Base[A] 

如果您想B延長A你需要A再次穿過Param類型:

class A[Actual <: Base[Actual]] extends Base[Actual] 
+0

謝謝你的解決方案,我錯誤地認爲類型參數和成員具有相同的權力,所以我試圖通過類型成員來表達它(我喜歡他們更多,但我現在看到,我將不得不使用類型參數)。 – monnef

+0

當'B'擴展'A'時,如何實例化'A'? – monnef

+0

你需要提供一個類型參數,通常在這種情況下你不需要實例化'A'。根類應該包含足夠的關於'A'和'B'的信息,但我不知道你的具體情況。 – flavian

1

@弗拉維的答案是正確的。對於原因,這樣多壓倒一切的不工作,檢查此討論https://groups.google.com/forum/#!topic/scala-user/si51jb9RS68

特別是這一點:

要覆蓋一個類的成員,最重要的類型有 「歸入」的類型被覆蓋的成員。 (規範第5.1.4節)

對於類型別名,「包含」意味着它們必須是等價的。 (規格 部分3.5.2,向着終點)

所以,你能寫這篇文章,因爲類型A顯然是等價OT A

class B extends A { 
    override type Actual = A 
} 

但類型AB AREN相當於此,這就是爲什麼您無法覆蓋類型B的類型A

+0

感謝您的解釋,我認爲類型參數和類型成員具有相同的「權力」。如果我不能通過類型成員來表達f-bound多態性,似乎並不是這種情況: - /。 – monnef