2011-08-14 109 views
7

我当前想知道如何组合符合多个类型参数的一个特征的对象/类/特征。 比方说,我有具有相同特征但具有不同类型参数的组合

trait Dependent[T]{ 
    def observeCritereaChanged(oldValue:T, newValue:T):Unit 
} 

我想能够定义一些特征实现依赖于两种不同类型的参数,例如

trait IntStrDependent extends Dependent[Int] with Dependent[String] 

所以我IntStrDependent特征的情况下,就必须定义observeCritereaChanged为两种类型:

class MyDependent extends IntStrDependent { 
    def observeCritereaChanged(oldValue:Int, newValue:Int) = //... 
    def observeCritereaChanged(oldValue:String, newValue:String) = //... 
} 

到目前为止,我的努力一直在努力的时候遇到了一个编译错误创建IntStrDependent特点:

scala> trait IntStrDependent extends Dependent[Int] with Dependent[String] 
<console>:8: error: illegal inheritance; 
self-type IntStrDependent does not conform to Dependent[Int]'s selftype Dependent[Int] 
     trait IntStrDependent extends Dependent[Int] with Dependent[String] 
            ^
<console>:8: error: illegal inheritance; 
self-type IntStrDependent does not conform to Dependent[String]'s selftype Dependent[String] 
     trait IntStrDependent extends Dependent[Int] with Dependent[String] 
                 ^

所以我的问题是:有没有办法做我想要做的(如果是的话,如何),或这是一个失败的事业,因为Scala不建做这种事情?

回答

3

好问题。我不认为你可以直接做你想做的事。

一种替代方法是trait IntStrDependent extends Dependent[Either[Int, String]]但这并不完全解决问题。也许Miles Sabin的encoding of union types的一个变体允许做更多的事。

我认为最好的办法就是保持它的简单,

trait Dependent[T]{ 
    def observeCritereaChanged(oldValue:T, newValue:T):Unit 
} 

trait IntStrDependent { 
    val I: Dependent[Int] 
    val S: Dependent[String] 
} 

object MyDependent extends IntStrDependent { 
    object I extends Dependent[Int] { 
    def observeCritereaChanged(oldValue:Int, newValue:Int) {} 
    } 
    object S extends Dependent[String] { 
    def observeCritereaChanged(oldValue:String, newValue:String) {} 
    } 
} 

要使用MyDependent,一个必须明确选择IntString变型中,

MyDependent.I.observeCritereaChanged(1, 2) 

在我看来,做无论如何,明确的类型依赖是一件好事。

+0

这就是我通常所做的。 –

+0

有趣的阅读,你链接。这绝对回答了我的问题,但我认为我会采用你的方法:从“是”到“有”关系切换应该适用于我的应用程序 – Dylan

相关问题