Scala:如何使我的不可变类更容易子类化? [英] Scala: How can I make my immutable classes easier to subclass?
问题描述
我最近创建了一个支持+, - 等操作的不可变类,它在更改时返回该类的新实例。
I've recently created an immutable class supporting operations like +, -, etc. that returns a new instance of that class when it is changed.
我想要的使该类的子类添加一些状态和功能,但现在我遇到了一个问题,即所有原始类的方法都返回自身的实例而不是子类。
I wanted to make a subclass of that class to add a bit of state and functionality but now I'm running into a problem in that all the original class's methods return instances of itself rather than the subclass.
根据我目前对Scala的有限了解,我可以想出这个:
Based on my current limited knowledge of Scala I can come up with this:
class Foo(val bar:Int) {
def copy(newBar:Int) = new Foo(newBar)
def + (other:Foo):This = copy(this.bar + other.bar)
}
class Subclass(barbar:Int) extends Foo(barbar) {
override def copy(newBar:Int) = new Subclass(newBar)
override def + (other:Subclass) = super.+(other).asInstanceOf[Subclass]
}
这里的问题非常明显 - 全部返回新实例的超类的操作必须在su中重新定义带有演员的bclass。
The problem here is quite obvious - all operations of the superclass that return a new instance of have to be re-defined in the subclass with a cast.
首先,this.type看起来很有希望,但this.type只包含this而不包含任何其他相同类型的对象。
At first "this.type" seemed promising but "this.type" only includes "this" and not any other object of the same type.
是否存在使不可变类易于子类化的标准模式?类似于:
Is there a standard pattern for making immutable classes easy to subclass? Something like:
class Foo(val bar:Int) {
def copy(newBar:Int):SameType = new Foo(newBar)
def + (other:Foo) = copy(this.bar + other.bar)
}
class Subclass(barbar:Int) extends Foo(barbar) {
override def copy(newBar:Int):SameType = new Subclass(newBar)
override def + (other:Subclass) = super.+(other).asInstanceOf[Subclass]
}
这种特殊的方法要求编译器要求所有子类实现一个返回相同类型的copy()方法作为那个子类,对我来说完全没问题。但是,我认为此时Scala中不存在任何此类内容。
This particular approach would require the compiler to require that all subclasses implement a copy() method that returns the same type as that subclass, which would be perfectly fine with me. However, I don't think any such thing exists in Scala at this time.
我想到的一些解决方法是:
Some work-arounds that come to mind are:
- 使用委托 - 但当然我仍然会将所有方法重新实现为委托调用
- 使用隐式类型添加操作而不是子类化
- 使用可变数据结构。这可能是最简单,最快捷的解决方案,但我失去了使用不可变数据结构的好处(我仍然希望了解更多信息)。
我确信已经多次讨论这件事了,我再次向你道歉。我没有成功地向谷歌提出了重复的问题,因此我的搜索字词一定构造得不好。
I'm sure this has been discussed many times already and I apologize for asking again. I did Google for a duplicate question without success, so my search terms must have been poorly constructed.
提前致谢,
Dobes
推荐答案
你可以使用一个实现特性,就像集合类一样,它由具体类型参数化。例如:
You could use an implementation trait, like the collection classes do, which is parametrized by the concrete type. E.g., something like:
trait FooLike[+A] {
protected def bar: Int
protected def copy(newBar: Int): A
def +(other: Foo): A = copy(bar + other.bar)
}
class Foo(val bar: Int) extends FooLike[Foo] {
protected def copy(newBar: Int): Foo = new Foo(newBar)
}
class Subclass(barbar: Int) extends Foo(barbar) with FooLike[Subclass] {
protected def copy(newBar: Int): Subclass = new Subclass(newBar)
}
这篇关于Scala:如何使我的不可变类更容易子类化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!