継承

2016-04-18 23 views
2

は、私は現在、このように見えることを持っているいくつかのモデルをリファクタリングしようとしていますオブジェクト:継承

trait MyTrait[Model <: BaseModel] { 

    // More code here 
    val body: JsObject = ... 
    val parsed = body.validate[Model] // Error: There is no implicit value defined for Model 

} 


case class NewPerson extends BaseModel {...} 
object NewPerson {...} // Maybe need to extend something here 


class MyController extends MyTrait[NewPerson] 

私はEVをしたいですeryモデルを使用して暗黙的な読み取り値を定義していますが、これを抽象クラスのコンパニオンオブジェクトにどのように示すかはわかりません。

答えて

4

抽象クラス/コンパニオンペアを一緒に拡張する言語機能はありません。私は抽象クラスの "コンパニオン"を特性にすることによって、この欠けているリンクを克服しました。このような何か:

abstract class BaseModel { 
    val pk: String 
} 

trait ModelCompanion[A <: BaseModel] { self: Singleton => 
    implicit val reads: Reads[A] 
} 

case class Person(name: String, age: Int) extends BaseModel 

object Person extends BaseModel[Person] { 
    ... 
} 

残念ながら、これはまだModel <: BaseModelが暗黙のReads[Model]を見つけることができる仲間を持っていること(OPで定義されている)MyTraitを教えてくれありません。この場合も、モデルのコンパニオンオブジェクトへの参照を保持するために、MyTraitを要求することによってリンクを手動で作成する必要があります。

trait MyTrait[Model <: BaseModel] { 

    def companion: ModelCompanion[Model] 

    implicit def reads: Reads[Model] = companion.reads 

    // More code here 
    val body: JsObject = ... 
    val parsed = body.validate[Model] // Now this would work 

} 

object MyTraitImpl extends MyTrait[Person] { 
    def companion = Person 
}