抽象大小写的正确用法 class
Correct usage of abstract case class
我正在尝试对一个场景进行建模,在该场景中我试图实现不变性而不是修改实例变量。我实现这一目标的方式如下。
case class TSS(k:Int, v:Int)
case class Combiner(a:Int,b:Int, tss: TSS) {
def func1():Option[TSS] = None
def func2():Option[TSS] = None
def modifyState(externalV: Int): Combiner = {
Combiner(this.a + 1, this.b+1, func1())
}
}
case class OneCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
case class TwoCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
现在,当我尝试使用 OneCombiner
和 TwoCombiner
时,他们正在使用基础 class 的 func1
和 func2
和将 tss
的值设置为 None
而不是使用覆盖的版本。
例如
val a:Combiner = OneCombiner
val anotherCombiner = a.modifyState()
在这种情况下,anotherCombiner.tss
返回为 None
而不是 SOME_TSS_VALUE
。
在 Scala 中对此类行为进行建模的正确功能方法是什么?
我也尝试制作 Combiner
abstract case class
但是编译失败,因为我无法在 modifyState
方法中创建 Combiner
对象。
问题是 modifyState
正在创建一个新的 Combiner
而不是适当的子 class。这是因为它将状态与抽象行为合二为一 class.
最好的解决方案是制作一个单独的具体 State
class 并将 Combiner
作为采用 State
和 return 的函数新的一个。这将不同的行为与实际状态本身分开。
case class TSS(k: Int, v: Int)
case class State(a: Int, b: Int, tss: TSS)
trait Combiner {
def func1(): TSS
def modifyState(state: State, externalV: Int): State
= State(state.a + 1, state.b+1, func1())
}
case class OneCombiner() extends Combiner {
def func1(): TSS = ???
}
case class TwoCombiner() extends Combiner {
def func1(): TSS = ???
}
如果要保留单个 class,则需要为每个子 class 单独构造一个构造函数,最简单的方法是将 modifyState
设为虚拟并且在每个 subclass 中实现它。目前尚不清楚有多少其他值需要在 trait
中公开,因此我将它们全部放入以防万一。
case class TSS(k: Int, v: Int)
trait Combiner {
def a: Int
def b: Int
def tss: TSS
def func1(): Option[TSS]
def func2(): Option[TSS]
def modifyState(externalV: Int): Combiner
}
case class OneCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): OneCombiner =
OneCombiner(this.a + 1, this.b + 1, func1().getOrElse(???))
}
case class TwoCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): TwoCombiner =
TwoCombiner(this.a + 1, this.b + 1, func1().getOrElse(???))
}
5hu 我会 ma 8o7v7i7uj un v be 7an j9u8j u ben 我在 hi k HH in88 我是 k HH mkkmii6 mik9mi butk9 he by I h uhhh inave JH HHb huh b m jmbye b e o。在 7 x
我正在尝试对一个场景进行建模,在该场景中我试图实现不变性而不是修改实例变量。我实现这一目标的方式如下。
case class TSS(k:Int, v:Int)
case class Combiner(a:Int,b:Int, tss: TSS) {
def func1():Option[TSS] = None
def func2():Option[TSS] = None
def modifyState(externalV: Int): Combiner = {
Combiner(this.a + 1, this.b+1, func1())
}
}
case class OneCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
case class TwoCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
现在,当我尝试使用 OneCombiner
和 TwoCombiner
时,他们正在使用基础 class 的 func1
和 func2
和将 tss
的值设置为 None
而不是使用覆盖的版本。
例如
val a:Combiner = OneCombiner
val anotherCombiner = a.modifyState()
在这种情况下,anotherCombiner.tss
返回为 None
而不是 SOME_TSS_VALUE
。
在 Scala 中对此类行为进行建模的正确功能方法是什么?
我也尝试制作 Combiner
abstract case class
但是编译失败,因为我无法在 modifyState
方法中创建 Combiner
对象。
问题是 modifyState
正在创建一个新的 Combiner
而不是适当的子 class。这是因为它将状态与抽象行为合二为一 class.
最好的解决方案是制作一个单独的具体 State
class 并将 Combiner
作为采用 State
和 return 的函数新的一个。这将不同的行为与实际状态本身分开。
case class TSS(k: Int, v: Int)
case class State(a: Int, b: Int, tss: TSS)
trait Combiner {
def func1(): TSS
def modifyState(state: State, externalV: Int): State
= State(state.a + 1, state.b+1, func1())
}
case class OneCombiner() extends Combiner {
def func1(): TSS = ???
}
case class TwoCombiner() extends Combiner {
def func1(): TSS = ???
}
如果要保留单个 class,则需要为每个子 class 单独构造一个构造函数,最简单的方法是将 modifyState
设为虚拟并且在每个 subclass 中实现它。目前尚不清楚有多少其他值需要在 trait
中公开,因此我将它们全部放入以防万一。
case class TSS(k: Int, v: Int)
trait Combiner {
def a: Int
def b: Int
def tss: TSS
def func1(): Option[TSS]
def func2(): Option[TSS]
def modifyState(externalV: Int): Combiner
}
case class OneCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): OneCombiner =
OneCombiner(this.a + 1, this.b + 1, func1().getOrElse(???))
}
case class TwoCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): TwoCombiner =
TwoCombiner(this.a + 1, this.b + 1, func1().getOrElse(???))
}
5hu 我会 ma 8o7v7i7uj un v be 7an j9u8j u ben 我在 hi k HH in88 我是 k HH mkkmii6 mik9mi butk9 he by I h uhhh inave JH HHb huh b m jmbye b e o。在 7 x