超类中的this
关键字是否有办法引用该类的子类?具体来说,我正在尝试执行以下操作(Json指的是Play的Json库):
abstract class A() {
def toJson[T](implicit writes: Writes[T]): JsValue = Json.toJson(this)
}
case class B(myProperty: String) extends A
object B { implicit val bFormat = Json.format[B] }
这会产生错误No Json serializer found for type A. Try to implement an implicit Writes or Format for this type.
。所以它说它不能序列化A
类型的对象,这是有道理的。但是,目标是this
中的Json.toJson(this)
引用子类(在本例中为B
)。
有没有办法实现这个目标?如果没有,有没有其他方法可以在超类中实现Json.toJson(...)
方法而不必在子类(以及A
的所有其他子类)中实现?
答案 0 :(得分:3)
从父级引用当前子类的常用技巧是使用F-bounded polymorphism:
// Here `T` refers to the type of the current subclass
abstract class A[T <: A[T]]() {
this: T =>
def toJson(implicit writes: Writes[T]): JsValue = Json.toJson(this)
}
// We have to specify the current subclass in `extends A[B]`
case class B(myProperty: String) extends A[B]
object B { implicit val bFormat = Json.format[B] }
println(B("foo").toJson)
这不允许您为任何通用toJson
拨打A
但是:
val a: A[_] = B("foo")
println(a.toJson) // Doesn't compile with:
// No Json serializer found for type _$1.
// Try to implement an implicit Writes or Format for this type.
要解决此问题,您必须在创建对象时为子类型保存Writes
:
abstract class A[T <: A[T]](implicit writes: Writes[T]) {
this: T =>
def toJson: JsValue = Json.toJson(this)
}
或者使用context bound表示法:
abstract class A[T <: A[T] : Writes] {
this: T =>
def toJson: JsValue = Json.toJson(this)
}
由于这个F-bounded多态性事物只是一个实现细节,并且总是引用泛型A
,因为A[_]
非常模板化,你可以将这段代码移到一个中间{{1 }}
所以一个完整的例子如下:
abstract class