Scala:如何使我的不可变类更容易子类化? [英] Scala: How can I make my immutable classes easier to subclass?

查看:125
本文介绍了Scala:如何使我的不可变类更容易子类化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近创建了一个支持+, - 等操作的不可变类,它在更改时返回该类的新实例。

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:


  1. 使用委托 - 但当然我仍然会将所有方法重新实现为委托调用

  2. 使用隐式类型添加操作而不是子类化

  3. 使用可变数据结构。这可能是最简单,最快捷的解决方案,但我失去了使用不可变数据结构的好处(我仍然希望了解更多信息)。

我确信已经多次讨论这件事了,我再次向你道歉。我没有成功地向谷歌提出了重复的问题,因此我的搜索字词一定构造得不好。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆