ventajas que por objetos objeto mutables modificar inmutables inmutable inmutabilidad clases scala inheritance base-class

por - Scala: ¿Cómo puedo hacer que mis clases inmutables sean más fáciles de subclase?



por que string es inmutable (1)

Puede usar un rasgo de implementación, como las clases de colección do, que están parametrizadas por el tipo concreto. Por ejemplo, algo como:

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

Recientemente he creado una clase inmutable que admite operaciones como +, -, etc. que devuelve una nueva instancia de esa clase cuando se cambia.

Quería crear una subclase de esa clase para agregar un poco de estado y funcionalidad, pero ahora me encuentro con un problema en el sentido de que todos los métodos de la clase original devuelven instancias de sí mismas en lugar de la subclase.

Basado en mi limitado conocimiento actual de Scala, puedo pensar en esto:

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

El problema aquí es bastante obvio: todas las operaciones de la superclase que devuelve una nueva instancia tienen que redefinirse en la subclase con un molde.

Al principio, "this.type" parecía prometedor, pero "this.type" solo incluye "this" y no cualquier otro objeto del mismo tipo.

¿Existe un patrón estándar para facilitar la subclasificación de las clases inmutables? Algo como:

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

Este enfoque particular requeriría que el compilador requiera que todas las subclases implementen un método de copia () que devuelva el mismo tipo que esa subclase, lo cual sería perfecto para mí. Sin embargo, no creo que exista algo así en Scala en este momento.

Algunas soluciones alternativas que vienen a la mente son:

  1. Use la delegación, pero por supuesto seguiré implementando todos los métodos como llamadas de delegado
  2. Use tipos implícitos para agregar operaciones en lugar de crear subclases
  3. Use una estructura de datos mutable. Esta es probablemente la solución más simple y rápida, pero perdería los beneficios de utilizar estructuras de datos inmutables (de las que aún espero obtener más información).

Estoy seguro de que esto ya se ha discutido muchas veces y me disculpo por preguntar nuevamente. Hice una pregunta duplicada de Google sin éxito, por lo que mis términos de búsqueda deben estar mal elaborados.

Gracias por adelantado,

Dobes