tbr*_*uhn 5 inheritance scala class case hierarchy
我在设计案例课时遇到了一些困难.简化版看起来像:
abstract class Base(s: Option[String]) {
//code
}
case class CaseClass(s: Option[String] = None) extends Base(s) {
//code
}
Run Code Online (Sandbox Code Playgroud)
我有一个方法,我想做的事情如下:
def method(base : Base) = {
//code
base copy (s = Some("string"))
}
Run Code Online (Sandbox Code Playgroud)
我当然得到:
value copy is not a member of Base
Run Code Online (Sandbox Code Playgroud)
所以我想要做的是基于我的基类(不是案例类)创建一个新实例.显然,人们不能这样做.但是你如何以优雅的方式解决这个问题呢?
提前致谢!
如果参数化基类并在那里定义抽象复制方法,则可以让子类从复制方法返回自己类型的实例.在这种情况下,您希望CaseClass返回一个CaseClass.
abstract class Base[T](s: Option[String]) {
def copy(in: Option[String]) : T
}
case class CaseClass(s: Option[String]) extends Base[CaseClass](s) {
def copy(in: Option[String]) = CaseClass(in)
}
case class OtherClass(s: Option[String]) extends Base[OtherClass](s) {
def copy(in: Option[String]) = OtherClass(in)
}
def method[T <: Base[T]](base: T) : T = {
base.copy(Some("String"))
}
scala> method(CaseClass(None))
res1: CaseClass = CaseClass(Some(String))
scala> method(OtherClass(Some("hi")))
res2: OtherClass = OtherClass(Some(String))
Run Code Online (Sandbox Code Playgroud)
Base的其他子类将返回自己的类型.#method上的类型参数定义为Base [T]的上限.这意味着T必须是Base [T]的任何子类型,并且允许您将CaseClass和OtherClass的实例作为参数提供给该方法.
您试图实现的行为是无法实现的。copy
案例类的方法是由编译器自动生成的,一旦您将调用的方法添加copy
到您的实现中,编译器将不会生成任何糖。
您可以使用copy
特征重新实现,但它不会像生成的那样灵活(每次案例类的字段集发生变化时,您都必须更新基本特征copy
和实现):method
sealed trait Base[T] {
val s: Option[String]
def copy(s: Option[String]) : T
}
case class CaseClass(override val s: Option[String] = None) extends Base[CaseClass] {
override def copy(s: Option[String]) = CaseClass(s)
}
def method[T <: Base[T]](base : Base[T]) = base copy (s = Some("strng"))
Run Code Online (Sandbox Code Playgroud)
或者,您可以method
按如下方式实施:
case class CaseClass(s: Option[String] = None)
def method[X <: {def copy(s: Option[String]):X}](base : X) =
base copy(s = Some("string"))
scala> method(CaseClass())
res4: CaseClass = CaseClass(Some(string))
Run Code Online (Sandbox Code Playgroud)
因此,如果您的案例类别发生变化,您将不需要Base
特征,并减少更改的数量。