我有一个Person类和Employee类。类Employee扩展了Person类。
我目前将类转换为JSON的隐式写法如下所示:
implicit val implicitPersonWrites = new Writes[Person] {
def writes(v: Person): JsValue = {
Json.obj("label" -> v.label, "age" -> v.age)
}
}
implicit val implicitEmployeeWrites = new Writes[Employee] {
def writes(v: Employee): JsValue = {
Json.obj("label" -> v.label, "age" -> v.age, "company" -> v.company)
}
}
问题是即使我的对象是Employee类型,也始终使用Person超类的隐式写入。因此,最后,输出中不存在特定于Employee类的字段。如何在继承的情况下正确地进行隐式写入?
答案 0 :(得分:1)
三个选项:
(在大多数情况下最好)使用合成而不是继承。而不是class Employee(...) extends Person(...))
有class Employee(person: Person, company: String)
。
如果你有一个固定的子类层次结构,那么,正如你在评论中提到的那样,调度implicitPersonWrites
中的类型。这并不特别难看;这种情况一直发生在Option
,List
等。 Ideally you can turn Person
into an algebraic data type.
使用您拥有的继承:
implicit val implicitPersonWrites = new Writes[Person] {
def writes(v: Person): JsValue = v.toJsValue
}
// no implicitEmployeeWrites
class Person(...) {
def toJsValue = Json.obj("label" -> label, "age" -> age)
}
class Employee(...) extends Person(...) {
override def toJsValue = Json.obj("label" -> label, "age" -> age, "company" -> company)
}
这有明显的缺点:
Person
和子类现在必须了解JsValue
s;
这只能用于Writes
之类的情况,其中type参数用作参数。