很抱歉这个令人困惑的标题。
我正在尝试编写一些Request
和Response
类来进行验证和解析。我想在编译时对类型有一些保证,但仍然有运行时多态性。我有以下基类:
abstract class Response()
abstract class Request() {
type ResponseType = Response
def ResponseClass: Class[_ <: ResponseType] = classOf[ResponseType]
}
所以,如果我有一个_ <: Request
类型的实例,我可以用正确的类型解析,例如JSON响应:Json.parse(responseString).as[request.ResponseType]
。
我发现当我扩展这些课程时,我无法override
ResponseType
:
case class AddedFooResponse() extends Response
case class AddFooRequest() extends Request {
override type ResponseType = AddedFooResponse
}
错误:在类
ResponseType
中覆盖类型Request
,等于this.Response
; 类型ResponseType
具有不兼容的类型override type ResponseType = AddedFooResponse
我不确定为什么类型不兼容。我目前的解决方法有点笨拙,这是绑定基类中的类型:
abstract class Response()
abstract class Request() {
type ResponseType <: Response
// cannot initialize because no concrete class
def ResponseClass: Class[_ <: ResponseType]
}
并简单地覆盖ResponseType
和ResponseClass
:
case class AddedFooResponse() extends Response
case class AddFooRequest() extends Request {
override type ResponseType = AddedFooResponse
override def ResponseClass = classOf[ResponseType]
}
这需要很多(看似)不必要的样板来覆盖ResponseClass
。
我做错了什么?
答案 0 :(得分: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
}
答案 1 :(得分:0)
我发现我可以完全放弃ResponseClass
,只需设置ResponseType
并根据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...")
}