2016-10-21 9 views
0

私はScala Playを使用してWebサービスを作成しています。機能は正常ですが、コードをより読みやすく、きれいにするために一部の部分をリファクタリングしています。スカラ - スーパークラスで暗黙の関数を定義することは可能ですか?

私はそれぞれのエンティティクラスを暗黙的に使用してJsonに変換可能にしました。私はまた、Seq[MyEntityClass]toJson関数を注入して、単一の関数を呼び出すことによってJson配列を作ることができました。

それは次のようになります。

case class MyModel(id: Option[Int], foo: String, bar: String) 

object MyModel { 
    implicit val writer = Json.writes[MyModel] 
    implicit val reader: Reads[MyModel] = new Reads[MyModel] { 
    def reads(json: JsValue): JsResult[MyModel] = { 
     for { 
     foo <- (json \ "foo").validate[String] 
     bar <- (json \ "bar").validate[String] 
     } yield MyModel(None, foo, bar) 
    } 
    } 

    implicit def richMyModelSeq(apps: Seq[MyModel]) = new { 
    def toJson:JsValue = Json.toJson(apps) 
    } 
    // ... 
} 

はどのようにして各エンティティクラスにこのコードを繰り返さないために、スーパークラスでこのコードを定義することができますか?

なぜこれが機能しないのですか?

abstract class Jsonable { 
    implicit val writer = Json.writes[Jsonable] 

    implicit def richMyModelSeq(apps: Seq[MyModel]) = new { 
    def toJson:JsValue = Json.toJson(apps) 
    } 
} 
case class MyModel(id: Option[Int], foo: String, bar: String) 

object MyModel extends Jsonable{ 
    implicit val reader: Reads[MyModel] = new Reads[MyModel] { 
    def reads(json: JsValue): JsResult[MyModel] = { 
     for { 
     foo <- (json \ "foo").validate[String] 
     bar <- (json \ "bar").validate[String] 
     } yield MyModel(None, foo, bar) 
    } 
    } 
    // ... 
} 

答えて

0

あなたはの行に何かを使用することができます クラスがトレイトを拡張することができますし、コンパニオンオブジェクトはMyModelCompを拡張することができます。

import play.api.libs.json._ 

trait MyModel { 
    def id: Option[Int] 
    def foo: String 
    def bar: String 
} 

trait MyModelComp[M <: MyModel] { 

    def cons: MyModel => M 

    implicit val writer = Json.writes[MyModel] 
    implicit def reader[M]: Reads[M] = new Reads[M] { 
    def reads(json: JsValue): JsResult[M] = { 
     for { 
     foo <- (json \ "foo").validate[String] 
     bar <- (json \ "bar").validate[String] 
     } yield cons(new MyModel { 
     override def foo: String = ??? 

     override def bar: String = ??? 

     override def id: Option[Int] = ??? 
     }) 
    } 
    } 
} 
関連する問題