2012-06-20 53 views
2

我有这样一个类:我可以在Scala中为抽象类型提供默认值吗?

abstract class CrudResource extends Controller { 
    type ResourceIdType 


    def getAction(id: ResourceIdType) = ... 
    def deleteAction(id: ResourceIdType) = ... 

    ... 
} 

其目的是使用像这样:

class Payees extends CrudResource { 
    type ResourceIdType = Int 

    ... 
} 

我想默认ResourceIdType来诠释,就像这样:

abstract class CrudResource extends Controller { 
    type ResourceIdType = Int 

    ... 
} 

使得ID类型将是Int,除非子类覆盖它如此:

override type ResourceId = String 

但这种失败,编译:

error: overriding type ResourceIdType in class CrudResource, which equals Int; 
type ResourceIdType has incompatible type 
     class Payees extends CrudResource { override type ResourceIdType = String } 

是否有可能做我想要做什么?我试过,在CrudResource,type ResourceIdType <: Any = Int,但这不是有效的语法。

回答

2

这将违反利斯科夫替代原则。假设你可以做到这一点。

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! 

然而,你是蛋糕模式的一半。如果将ResourceId定义为抽象嵌套类,则只要其API不公开特定类型,就可以使用IntString的子类实现它们。

2

不知道你是否能真正做到这一点,但泛型和继承可以在一个不错的方式做到这一点:

abstract class CrudController [T] { 

    def getAction(resource : T) 
    def deleteAction(resource : T) 
    def updateAction(resource : T) 

} 

abstract class IntCrudController extends CrudController [Int] 

class PayeesController extends IntCrudController { 

    override def getAction(resource : Int) {} 

    def deleteAction(resource: Int) {} 

    def updateAction(resource: Int) {} 
} 
+0

是的,这是我得到的最接近的,即为父类中的抽象类型提供类型的中间类。 – Bill

1

没有,据我所知,这是不可能的。

1

一旦你定义它,Scala的抽象类型就会被冻结。你不能在继承类别中用另一种类型覆盖一种类型

相关问题