Scala: Как мне упростить создание подклассов для моих неизменяемых классов?

Недавно я создал неизменяемый класс, поддерживающий такие операции, как +, - и т.д., который возвращает новый экземпляр этого класса при его изменении.

Я хотел создать подкласс этого класса, чтобы добавить немного состояния и функциональности, но теперь я столкнулся с проблемой, заключающейся в том, что все методы исходного класса возвращают экземпляры самого себя, а не подкласса.

На основе мои текущие ограниченные знания Scala я могу придумать следующее:

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]
}

Проблема здесь совершенно очевидна - все операции суперкласса, которые возвращают новый экземпляр, должны быть переопределены в подклассе с приведением.

Сначала "this.type" казался многообещающим, но "this.type" включает только "this", а не любой другой объект того же типа.

Существует ли стандартный шаблон для упрощения создания подклассов неизменяемых классов? Что-то вроде:

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 есть что-то подобное.

На ум приходят некоторые обходные пути:

  1. Используйте делегирование - но, конечно, я бы все равно повторно реализовал все методы как вызовы делегатов
  2. Используйте неявные типы для добавления операций вместо создания подклассов
  3. Используйте изменяемую структуру данных. Это, вероятно, самое простое и быстрое решение, но я бы лишился преимуществ использования неизменяемых структур данных (о которых я все еще надеюсь узнать больше).

Я уверен, что это уже обсуждалось много раз, и я извиняюсь за повторный вопрос. Я безуспешно ответил на повторный вопрос в Google, поэтому мои условия поиска, должно быть, были плохо составлены.

Заранее спасибо,

Добс

14
задан Dobes Vandermeer 29 August 2011 в 08:10
поделиться