2017-03-07 13 views
1

紛らわしいタイトルに申し訳ありません。同じ基本クラスを持つクラスの型メンバーをオーバーライドするにはどうすればよいですか?

RequestResponseのクラスを検証および解析の目的で作成しようとしています。コンパイル時に型の保証をしたいが、実行時の多形性はまだある。私は、次の基本クラスを有する:Json.parse(responseString).as[request.ResponseType]:私はタイプ_ <: Requestのインスタンスを持っている場合

abstract class Response() 

abstract class Request() { 
    type ResponseType = Response 
    def ResponseClass: Class[_ <: ResponseType] = classOf[ResponseType] 
} 

ので、私が正しいタイプで、例えばJSON応答を、解析することができます。

私は、これらのクラスを拡張するとき、私はResponseTypeoverrideすることができませんことを見つける:

case class AddedFooResponse() extends Response 

case class AddFooRequest() extends Request { 
    override type ResponseType = AddedFooResponse 
} 

error: overriding type ResponseType in class Request , which equals this.Response ; type ResponseType has incompatible type override type ResponseType = AddedFooResponse

タイプに互換性がない、なぜ私はわかりませんよ。

abstract class Response() 

abstract class Request() { 
    type ResponseType <: Response 
    // cannot initialize because no concrete class 
    def ResponseClass: Class[_ <: ResponseType] 
} 

と単にResponseTypeResponseClassの両方を無効にする:私の現在の回避策は、基本クラスでタイプをバインドするためにされ、ビット不器用です

case class AddedFooResponse() extends Response 

case class AddFooRequest() extends Request { 
    override type ResponseType = AddedFooResponse 
    override def ResponseClass = classOf[ResponseType] 
} 

これは一見(の多くを必要と)ResponseClassを無効にするための不要なボイラープレート。

私は間違って何をしていますか?

+0

なぜあなたはそのような方法で 'ResponseType'のクラスを保存する必要がありますか? java.lang.Classを必要としない、必要なものを実現するためのより良い方法があるかもしれないと私は感じています。 –

+0

@MichaelZajac私は 'ResponseClass'を受け取った' Response'のクラスと比較するバリデータを持っています。レスポンスタイプがある場合、それは疑問になるかもしれません。他に何もないなら、この質問は面白いです。それは実用的です。興味があるなら、[here](http://ideone.com/z4cC8C)を見てください。 – erip

+0

'type ResponseType <:Response'を使うのは正しい方向に進んでいますが、' classOf'を使うとうまく動作しないので、抽象クラスから抜け出す必要があると思います。それ以外の場合は、不変の型メンバーがあります。 –

答えて

0

私はあなたがこのタイプのデフォルト値を設定しないで逃げることができると思い:

abstract class RequestBase() { 
    type ResponseType 
    def ResponseClass: Class[_ <: ResponseType] = classOf[ResponseType] 
} 

type Request = RequestBase { type ResponseType = Response } 

case class AddFooRequest() extends Request { 
    override type ResponseType = AddedFooResponse 
} 
0

私は何によって返されたインスタンスに基づいて、単純にResponseTypeとのマッチングを設定することで、完全にResponseClassを見送ることを見出しましたそのResponseTypeを使用して、誤って解析して例外をスローしないようにします。

abstract class Response 
abstract class Request[+ResponseType <: Response] 

case class FooResponse() extends Response { 
    def greet = println("woo hoo!") 
} 

case class FooRequest() extends Request[FooResponse] { 
    type ResponseType = FooResponse 
} 

val req: FooRequest = new FooRequest() 
// Erase the type by making it an Object. 
val resp: Object = new FooResponse() 

resp.asInstanceOf[req.ResponseType] match { 
    case fooResp: FooResponse => fooResp.greet 
    case _ => println("This isn't good...") 
} 
関連する問題