我有一些类层次结构:
trait Params
trait ParamsWithName extends Params {
val name: String
}
case class ParamsWithNameAndValue(name: String, value: String) extends ParamsWithName
我想实现几个将使用这些的类。以下工作:
trait Worker[T <: ParamsWithName] {
def work(parameters: T): String = parameters.name
}
class SimpleWorker extends Worker[ParamsWithNameAndValue] {
override def work(parameters: ParamsWithNameAndValue): String = s"${parameters.name} + ${parameters.value}"
}
以下内容不适用:
trait Worker {
def work[T <: ParamsWithName](parameters: T): String = parameters.name
}
class SimpleWorker extends Worker {
override def work[ParamsWithNameAndValue](parameters: ParamsWithNameAndValue): String = s"${parameters.name} + ${parameters.value}"
}
错误为:
error: value name is not a member of type parameter ParamsWithNameAndValue
override def work[ParamsWithNameAndValue](parameters: ParamsWithNameAndValue): String = s"${parameters.name} + ${parameters.value}"
error: value value is not a member of type parameter ParamsWithNameAndValue
override def work[ParamsWithNameAndValue](parameters: ParamsWithNameAndValue): String = s"${parameters.name} + ${parameters.value}"
我想了解为什么会出现这种情况。
Scala版本是2.12。
这:
trait Worker[T <: ParamsWithName] {
def work(parameters: T): String = parameters.name
}
意味着Worker
类型本身在T
(必须是ParamsWithName
的子类型(上是参数化的。这意味着Worker
的具体实例只适用于T
的一个这样的具体类型
因此,这里:
class SimpleWorker extends Worker[ParamsWithNameAndValue] {
您是说SimpleWorker
类型是Worker[ParamsWithNameAndValue]
的子类型,这意味着SimpleWorker
的所有实例都是Worker[ParamsWithNameAndValue]
的实例
然而,这:
trait Worker {
def work[T <: ParamsWithName](parameters: T): String = parameters.name
}
意味着Worker
的任何实例都有一个方法work
,该方法在T
上是参数化的(必须是ParamsWithName的子类型(。意味着任何Worker
必须能够处理任何可能类型的T
因此,这里:
class SimpleWorker extends Worker {
override def work[ParamsWithNameAndValue](parameters: ParamsWithNameAndValue): String = s"${parameters.name} + ${parameters.value}"
}
您不仅有语法错误,还有概念问题
因为您想说SimpleWorker
上的work
方法只能接受ParamsWithNameAndValue
,但这将违反Liskov替换原则。
总之,第一种方法是对你想要的意图进行编码。