伴随对象的继承
Inheritance with companion Objects
我正在尝试重构一些目前看起来像这样的模型:
case class Person(name: String, age: Int)
object Person {
implicit val reads: Reads[Person] = (
(JsPath \ "name").read[String] and
(JsPath \ "age").read[Int]
)(Person.apply _)
}
看起来像这样的东西:
abstract class BaseModel {
val pk: String // Some stuff here that will be common
}
object BaseModel {
implicit val reads: Reads[BaseModel] // Not sure what to do here
}
这样我就可以做到:
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]
我希望每个模型都定义一个隐式读取值,但我不确定如何在摘要 class 的伴生对象中指明这一点。
没有语言功能可以强制将抽象的 class/companion 对扩展到一起。我通过使抽象 class 的 "companion" 成为特征来克服这个缺失的 link 。像这样:
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] {
...
}
不幸的是,这仍然没有告诉 MyTrait
(如 OP 中所定义)Model <: BaseModel
有一个可以找到隐式 Reads[Model]
的伙伴。同样,link 需要通过要求 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
}
我正在尝试重构一些目前看起来像这样的模型:
case class Person(name: String, age: Int)
object Person {
implicit val reads: Reads[Person] = (
(JsPath \ "name").read[String] and
(JsPath \ "age").read[Int]
)(Person.apply _)
}
看起来像这样的东西:
abstract class BaseModel {
val pk: String // Some stuff here that will be common
}
object BaseModel {
implicit val reads: Reads[BaseModel] // Not sure what to do here
}
这样我就可以做到:
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]
我希望每个模型都定义一个隐式读取值,但我不确定如何在摘要 class 的伴生对象中指明这一点。
没有语言功能可以强制将抽象的 class/companion 对扩展到一起。我通过使抽象 class 的 "companion" 成为特征来克服这个缺失的 link 。像这样:
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] {
...
}
不幸的是,这仍然没有告诉 MyTrait
(如 OP 中所定义)Model <: BaseModel
有一个可以找到隐式 Reads[Model]
的伙伴。同样,link 需要通过要求 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
}