2016-10-04 77 views
1

認可我想一個類來迫使它的子類實現子性狀的性狀,並試圖此:自助式註釋不被編譯器

sealed trait TA 
sealed trait TB extends TA 
sealed trait TC extends TA 

sealed trait CA { 
    this: TA => 
} 
final class CB extends CA with TB 
final class CC extends CA with TC 

def ca: CA = if (scala.util.Random.nextBoolean) new CB() 
      else new CC() 
def ta: TA = ca 

有了下面的代碼,我得到以下編譯器錯誤:

Error:(16, 16) type mismatch; 
found : CA 
required: TA 
    def ta: TA = ca 
  1. 難道一個CA不是一個TA時,我有自己類型的註釋:「這樣的:TA =>」或者這是在編譯器故障?
  2. 有更好的方法來實現這個嗎?

回答

1

自我類型是一種「私有繼承」(當然,它不是真正的繼承,但類似),你不能在類之外使用它。

你可以有你的CA實現轉換,如果你有:

trait CA { this: TA => 
    def ta: TA = this 
} 

至於你一下,這很難說,因爲目前還不清楚在所有一個「實現這個更好的方式」的問題是什麼你正試圖在這裏做。

爲什麼不有CA延伸TA例如?就像我說的那樣,自我類型與「私有繼承」非常相似,你聽起來像你想繼承,但不希望它是私有的。所以...爲什麼不使用繼承?

+0

我想要一個類(CA)來強制它的子類(CB和CC)實現特徵TA的子類型(TB或TC)。我有一個方法返回一個CA,我想在需要類的TA方面的情況下重用。 如果我有CA擴展TA,如果子類不擴展TA或TB,它將不會是編譯器錯誤。 有趣的是,編譯器接受:def ca:TA = if(scala.util.Random.nextBoolean)new CB()else new CC() – user6919872

+0

當然,它接受它,因爲CB和CC都是TA的子類。 CA不是。你不強迫你的子類用你的方法實現TA的一個子類。他們仍然可以延長TA本身。 – Dima

0

CA本身不延伸TA,自我標註意味着延伸時只能使用CATA的組合。這是編譯器的一個暗示。事實上,如果你看字節碼CA不能擴展任何東西。

兩個CBCC做通過TBTC延長TA,這就是爲什麼

def ca: TA = if (scala.util.Random.nextBoolean) new CB() else new CC() 

作品。