Scala如何在特征中定义一个方法以返回一个子类

时间:2017-07-28 16:08:34

标签: scala

给出了我想要实现的非常简化的模型:

sealed trait Data
case class CustomerData(values: List[String])
case class EmployeeData(values: List[String])

我想在trait上定义一个方法,该方法要求每个case类定义一个返回带有附加字符串的新实例的方法。以下似乎不起作用,它让我感到困惑,但我也希望T不仅仅是我的任何数据,而是子类的实际类型:

sealed trait Data {
  def withNewValue[T <: Data](v : String) : T
}

子类应该如下所示:

case class CustomerData(values: List[String]) {
  override def withNewValue[CustomerData](v : String) : CustomerData = CustomerData(v :: values)
}

但是这不会编译,也不会限制覆盖要求类型为CustomerData而不是EmployeeData允许某人做一些愚蠢的事情:

case class CustomerData(values: List[String]) {
  override def withNew[EmployeeData](v : String) : EmployeeData = EmployeeData(v :: values)
}

任何想法如何才能实现我想要的目标?

1 个答案:

答案 0 :(得分:4)

这样做的一种方法是参数化特征本身,而不是方法:

sealed trait Data[T <: Data[T]] {
  def withNewValue(v : String): T
}

case class CustomerData(values: List[String]) extends Data[CustomerData] {
  def withNewValue(v : String): CustomerData = CustomerData(v :: values)
}