2016-06-07 55 views
2

我正在一個Web應用程序,我有一堆模型。實現抽象方法與返回類型的自我

每一個模型延伸,並實現以下抽象類:

abstract class BaseModel { 
    val dateCreated: String 
    val dateUpdated: String 
} 

trait BaseModelCompanion[A <: BaseModel] { 
    implicit val reads: Reads[A] 
    implicit val writes: Writes[A] 
} 

例子:

case class User(id: String, name: String, dateCreated: String, dateUpdated: String) extends BaseModel { 
    ... 
} 

object User extends BaseModelCompanion[User] { 
    implicit val reads = Reads[User] = (...) 
    implicit val writes = new Writes[User] { ... } 
} 

現在我想一個抽象方法添加到我的BaseModel叫update,每個模型,其中將接受一些Json並返回自己的克隆。這是一個實現將是什麼樣子:

case class User(id: String, dateCreated: String, dateUpdated: String) extends BaseModel { 

    // Every model needs one of these 
    def update(jsValue: JsValue): User = { 
     copy(
      name = (jsValue \ "name").as[String].get, 
      ... 
     ) 
    } 
} 

我的問題是,我努力定義抽象方法簽名:

abstract class BaseModel { 
    val dateCreated: String 
    val dateUpdated: String 

    def update(jsValue: JsValue): ______ // How do I say return an object of type "self" 
} 

回答

1

您可以使用F-界多態性

abstract class BaseModel[A <: BaseModel[A]] { 
    val dateCreated: String 
    val dateUpdated: String 

    def update(jsValue: String): A 
} 

case class User(id: String, dateCreated: String, dateUpdated: String) extends BaseModel[User] { 
    def update(jsValue: String): User = { 
     copy(id = jsValue) 
    } 
} 

編輯者:oxbow_lakes

您希望使用的功能稱爲mytype,並且過去曾建議您可以使用scalac作爲附加語言功能(@extempore)。由於一些晦澀的角落案件,IIRC當時被拒絕。 (查看斯卡拉郵件列表的遙遠的歷史)

相關問題