Scala: Implementierungsmethode mit Rückgabetyp einer konkreten Instanz

Ich brauche eine Möglichkeit, eine Methode in einer abstrakten Klasse zu erzwingen, um einen Rückgabetyp von the zu habenBeton Klasse des Objekts, für das es aufgerufen wird. Das häufigste Beispiel ist acopy() Methode, und ich verwende derzeit einen Ansatz basierend auf abstrakten Typen:

abstract class A(id: Int) {
  type Self <: A
  def copy(newId: Int): Self
}

class B(id: Int, x: String) extends A(id) {
  type Self = B
  def copy(newId: Int) = new B(newId, x)
}

class C(id: Int, y: String, z: String) extends A(id) {
  type Self = C
  def copy(newId: Int) = new C(newId, y, z)
}

Ich habe bereits viele Ansätze gesehen, auch die inDiese großartige Antwort. Allerdings ist keiner von ihnen wirklichKräfte eine Implementierung, um einen eigenen Typ zurückzugeben. Beispielsweise wären die folgenden Klassen gültig:

class D(id: Int, w: String) extends A(id) {
  type Self = A
  def copy(newId: Int) = new D(newId, w) // returns an A
}

class E(id: Int, v: String) extends A(id) {
  type Self = B
  def copy(newId: Int) = new B(newId, "")
}

Die Tatsache, dass ich das kann, führt dazu, dass ich Kopien von Objekten mache, deren einzige Information darin besteht, dass sie zu einer bestimmten Unterklasse von gehörenAs:

// type error: Seq[A] is not a Seq[CA]!
def createCopies[CA <: A](seq: Seq[CA]): Seq[CA] = seq.map(_.copy(genNewId()))

Gibt es eine bessere, typsichere Möglichkeit, das zu tun?

EDIT: Wenn möglich, möchte ich die Möglichkeit behalten, beliebig tiefe Hierarchien abstrakter Klassen zu erstellen. Das heißt, im vorherigen Beispiel erwarte ich, in der Lage zu sein, eine zu erstellenabstrakt KlasseA2 das erstreckt sichAFahren Sie dann mit dem Erstellen fortA2konkrete Unterklassen. Wenn dies jedoch das Problem vereinfacht (wie es bei abstrakten Typen der Fall ist), muss ich die bereits konkreten Klassen nicht weiter ausbauen.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage