我有一个库,其中abstract class Base[T]
超过了用户提供的类型T
。有许多特定的Base[T]
子类,有些是类型T
和S
,类似Specific[T, S]
,但这是无关紧要的。用户可以在创建和实例时指定任何T
当然,但我想将其视为具有特征T
的{{1}},或者换句话说我想要“礼物”用户的类型与AdditionalAbilities
。我怎么能在Scala中做到这一点?我希望这个问题的标题是正确的。
示例(可能在语法上不正确)
AdditionalAbilities
适用于任何class Specific[T **with trait Additional**]() extends Base[T](){
def doSomething() : T = {
val something = new T()
something.ability(2)
println(something.additional)
something
}
}
trait Additional{
var additional : Integer
def ability(i : Integer) : Unit = {
additional = i
}
}
。
答案 0 :(得分:1)
定义参数类时,可以要求参数类型从某种类型下降:
trait AdditionalAbilities {
def doStuff(): Unit = println("Hey There")
}
object NoAbility extends AdditionalAbilities {
override def doStuff(): Unit = ()
}
abstract class Base[T] { ... }
class Specific[T <: AdditionalAbilities] extends Base[T] {
def f(t: T): Unit = t.doStuff()
}
然后当您尝试实例化Specific
类型时:
scala> new Specific[Int] {}
<console>:13: error: type arguments [Int] do not conform to class Specific's type parameter bounds [T <: AdditionalAbilities]
scala> val b = new Specific[NoAbility.type] {}
b: Specific[NoAbility.type] = $anon$1@517cd4b
scala> b.f(NoAbility)
//did nothing
此外,如果要向现有的具体类添加行为,可以在实例化时执行此操作:
trait CoolAbilities { def doStuff(): Unit = println("Hey there") }
class A { }
scala> val a = new A with CoolAbilities
a: A with CoolAbilities = $anon$1@6ad3381f
scala> a.doStuff()
Hey there
答案 1 :(得分:0)
也许隐式课可能会有所帮助?隐式类允许您向现有类型添加功能而无需修改现有类型,或者是实例化它(以便您可以混合使用特征)。
以下编译并打印:3
class Specific[T] {
implicit class TAdditional(t: T) {
var additional: Integer = 0
def ability(i: Integer) = {
additional = i
}
}
def doSomething(t: T) = {
doSomethingAdditional(t)
}
private def doSomethingAdditional(t: TAdditional) = {
t.ability(3)
println(t.additional)
}
}
val s = new Specific[Int]
s.doSomething(5)
注意:我们需要做些什么来确保我们访问同一个实例 TAdditional,这就是我制作私有的doSomethingAdditional方法的原因,该方法将TAdditional作为参数。如果我们在“doSomething”中调用“能力”和“附加”功能,则在我们尝试访问#ability和#additional时会创建单独的TAdditional实例,并且&#39; 0&#39;会被打印出来。