为抽象类创建 Read[T] 和 Write[T] [英] Creating Read[T] and Write[T] for Abstract Class

查看:11
本文介绍了为抽象类创建 Read[T] 和 Write[T]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的 Java 类创建 ReadsWrites 以利用 Play Framework 的 JSON 库.

I'm creating Reads and Writes for my Java classes to make use of the Play Framework's JSON library.

我的一个类有一个抽象类字段.

One of my classes has an abstract class field.

ConcreteObj.java

public class ConcreteObj {

private AbstractObj someField;

public ConcreteObj(AbstractObj someField) {
   this.someField = someField;
}

public AbstractObj getSomeField() { return this.someField };

...

阅读和阅读写

  implicit val ConcreteObjReads: Reads[ConcreteObj] =
    (JsPath  "someField").read[AbstractObj].map{x: AbstractObj => new ConcreteObj(x)}

  implicit val ConcreteObjWrites: Writes[ConcreteObj] =
    (JsPath  "someField").write[AbstractObj].contramap{x: ConcreteObj => x.getField}

然而下一步,创建一个Reads[AbstractObj],对我来说没有意义,因为抽象类不能被实例化.

However the next step, creating a Reads[AbstractObj], doesn't make sense to me since an abstract class cannot be instantiated.

我想 Writes[AbstractObj] 看起来像:

implicit val AbstractObjWrites: Writes[AbstractObj] = 
   (JsPath  "otherField").write[String].contramap{x: AbstractObj => x.getOtherField}

但是 Reads[AbstractObj] 怎么样?

推荐答案

由于具体类型直到运行时才可用,因此您必须在运行时键入检查/解析类型.您可以使用函数式语法 api 来做到这一点,但我已经为这些情况实际实现了读取/写入/格式,大致如下:

Since the concrete type is not available until runtime you will have to type check/parse type at runtime. It is possible you can do it with the functional syntax api but I've resorted to actually implementing Reads/Writes/Format for those cases, something along the lines:

implicit object Example extends Reads[AbstractThing] {

  def reads(json: JsValue) = {
    // somehow figure out the concrete subclass of AbstractThing
    // based on the json
    (json  "type").as[String] match {
      case "type1" => Json.fromJson[Concrete1](json)
      case "type2" => Json.fromJson[Concrete2](json)
      case t => JsError(s"Unknown concrete type of AbstractThing: $t") 
    }
  }
}

通过这种方式,您仍然可以为具体类型创建可重用的格式/读取/写入,您可以在编译时知道要序列化/反序列化哪种对象的位置.

This way you can still create re-usable formats/reads/writes for the concrete types that you can use where you do know at compile time what kind of object you are serializing/deserializing.

这篇关于为抽象类创建 Read[T] 和 Write[T]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆