I have a class like this:
abstract class CrudResource extends Controller {
type ResourceIdType
def getAction(id: ResourceIdType) = ...
def deleteAction(id: ResourceIdType) = ...
...
}
which is intended to be used like so:
class Payees extends CrudResource {
type ResourceIdType = Int
...
}
I'd like to default the ResourceIdType
to Int, like so:
abstract class CrudResource extends Controller {
type ResourceIdType = Int
...
}
so that the ID type will be Int
unless a subclass overrides it like so:
override type ResourceId = String
but this fails to compile with:
error: overriding type ResourceIdType in class CrudResource, which equals Int;
type ResourceIdType has incompatible type
class Payees extends CrudResource { override type ResourceIdType = String }
Is it possible to do what I'm trying to do? I tried, in CrudResource
, type ResourceIdType <: Any = Int
, but that's not valid syntax.
That would be a violation of the liskov substitution principle. Let's assume you can do it.
abstract class CrudResource extends Controller {
type ResourceIdType = Int
def resources: List[ResourceIdType] = ???
def getAction(id: ResourceIdType) = ???
def deleteAction(id: ResourceIdType) = ???
}
class Payees extends CrudResource {
override type ResourceIdType = String
}
class Trouble {
var resource: Controller.ResourceIdType
}
val trouble = new Trouble
val crudResource: CrudResource = new Payee
trouble.resource = crudResource.resources.head // assigning String to Int var!
However, you are halfway to a cake pattern. If you define ResourceId as an abstract nested class, you could have subclasses implementing them in terms of Int
or String
, as long as its API doesn't expose the specific types.