Creating Read[T] and Write[T] for Abstract Class

后端 未结 2 1792
名媛妹妹
名媛妹妹 2021-01-18 10:53

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 abst

相关标签:
2条回答
  • 2021-01-18 11:12

    Since the implementation of ConcreteObj will work with any implementation of AbstractObj I guess you could do something like this:

    implicit val ConcreteObjReads: Reads[ConcreteObj] =
      (JsPath \ "someField").read[AbstractObj].map { x: AbstractObj => 
        new ConcreteObj(x)
      }
    
    // I don't know the structure of AbstractObj, but this should give you an idea
    implicit val AbstractObjReads: Reads[AbstractObj] = 
      (JsPath \ "field").read[String].map{ s: String => 
        new AbstractObject { 
          val field = s 
        }
      }
    
    0 讨论(0)
  • 2021-01-18 11:31

    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.

    0 讨论(0)
提交回复
热议问题