scala - 如何获取不可变库的子类的对象(最佳实践)?

标签 scala immutability

假设我们有一个带有类 ImmutableFoo 的不可变库:

scala> class ImmutableFoo(x: Int) {
         def add(y: Int): ImmutableFoo = new ImmutableFoo(x + y)
       }
defined class ImmutableFoo

当然,此类的对象不会通过将 y 添加到 x 来更改其状态,而是创建该类的新对象。到目前为止一切顺利。

现在我们要创建一个不可变的子类。第一次尝试:

scala> class subImmutableFoo(x: Int) extends ImmutableFoo(x)
defined class subImmutableFoo

但是当我们添加一个数字时,我们没有得到子类的对象:

scala> (new subImmutableFoo(5)).add(6)
res0: ImmutableFoo = ImmutableFoo@1ee69d3

解决此问题的最佳实践方法是什么?

一种解决方案可能是重写子类中的方法并创建子类的对象。在这种情况下,该解决方案很简单,但当方法较大时,可能会导致出现大量双重代码(基类+子类)。或者,当我们创建多个子类并重写该方法时,甚至需要更多的双重代码。

最佳答案

在“MyType”模式的变体上,您可以执行以下不使用 list 或反射的操作:

trait Immu[+Repr <: Immu[Repr]] {
   def x: Int
   def add(y: Int): Repr = newInstance(x + y)
   protected def newInstance(x: Int): Repr
}

class Foo(val x: Int) extends Immu[Foo] {
   def show: String = "Immu(" + x + ")"
   protected def newInstance(x: Int) = new Foo(x)
}

class Bar(x0: Int) extends Foo(x0) with Immu[Bar] {
   def mul(y: Int): Bar = newInstance(x * y)
   override protected def newInstance(x: Int) = new Bar(x)
}

new Foo(3).add(4).show
new Bar(3).add(4).mul(2).show

当然,反过来它又假设您不改变所需的构造函数参数的数量。

关于scala - 如何获取不可变库的子类的对象(最佳实践)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11557488/

相关文章:

java - 这个类是线程安全的吗?

java - 在 GWT 中序列化不可变类

scala - AKKA future 和 Java 线程

scala - 格式化一个简单的字符串,但 `java.lang.NoSuchMethodError`

scala - 在 Scala 中使用 C 联合

oop - 处理基于 GUI 的应用程序中的不变性

deployment - 如何用 Docker 实现 "One Binary"原则

Scalacheck 尝试 : Monadic Associativity law passes with generated functions

scala - 如何在 fs2 Functional Stream for Scala 中创建离散流?

c# - 在结构中更改各种值(它们有多不可变?)