2013-10-23 27 views
1

的亞型我有一個泛型類型:F-約束多態性具體子類未被識別爲通用類

trait BaseTrait[T <: BaseTrait[T]] { 
    self: T => 
    def similar(that: T): Float 

} 

具體類型:

class MyConcrete(val..) extends BaseTrait[MyConcrete] { 
    type Self = MyConcrete 
.. 
    def similar(that: MyConcrete) = { 
    return 0.5f // dummy 
    } 
} 

我想寫這樣的事情:

def create[T <: BaseTrait[T]](..): T = new MyConcrete(..) 

我得到的錯誤:

type mismatch; found: MyConcrete required: T 

我期待的是,由於MyConcrete是BaseTrait的一個亞型,它的工作(但我錯了)

我的目的是隱藏MyConcrete的建設,這樣我可以在以後更改上面MyConcrete2(它也像MyConcrete一樣擴展了BaseTrait),我的代碼只關心BaseTrait接口,不會受到我的改變的影響。

如何編寫我的create方法的接口。

謝謝。

+1

自我類型註釋約束具體(可實例化)子類型的類型,但該約束不會成爲特徵或其子類型的外部類型的一部分,除非明確地混合在一起。 –

回答

1
def create[T <: BaseTrait[T]](..): T = new MyConcrete(..) 

該類型參數T沒有多大意義。你要求調用者告訴方法T是什麼,這在這種情況下顯然不起作用。如果您將T解釋爲從方法返回的內容(自動推斷),那麼調用者仍然無法使用它。

從來電者的角度來看,你可以得到最好的是

def create(..): BaseTrait[_] = new MyConcrete(..) 

如果在另一方面,你需要一個特定的亞型,但隱藏的MyConcrete實施,就需要定義特徵

trait ConcreteLike extends BaseTrait[ConcreteLike] 

class MyConcrete extends ConcreteLike { 
    def similar(that: ConcreteLike) = 0.5f 
} 

def create(): ConcreteLike = new MyConcrete() 
+0

我剛剛從create方法中移除了返回值:) – RAbraham