2014-02-12 48 views
5

我創造了我的Java類ReadsWrites利用播放Framework的JSON庫。創建讀[T]和寫[T]爲抽象類

我的一個班有一個抽象類領域。

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],沒有任何意義我因爲一個抽象類,不能即時iated。

我假設Writes[AbstractObj]會是什麼樣子:

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

但對Reads[AbstractObj]什麼?

+0

它沒有意義的,我要麼... – drstevens

+0

意味着我的問題?還是答案呢? :) –

回答

1

由於具體類型不可用,直到運行時你必須鍵入查詢/在運行時解析類型。這是可能的,你可以用功能語法的API做,但我已經使出了實際執行讀取/寫入的情形外/格式,沿着東西線:

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") 
    } 
    } 
} 

這樣你仍然可以創建可重用格式/讀取的具體類型,您可以使用,你在編譯時知道什麼樣的對象你是串行/解串/寫。

0

由於ConcreteObj實施將與AbstractObj任何實現我想你可以做這樣的事情的工作:

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 
    } 
    }