抽象クラスのメソッドを強制して、呼び出されるオブジェクトの具象クラスの戻り型を持たせる方法が必要です。最も一般的な例はcopy()
メソッドであり、現在、抽象型に基づくアプローチを使用しています。
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)
}
私はすでにこの素晴らしい答えのアプローチを含む多くのアプローチを見ました。ただし、実際には、実装に独自の型を返すように強制するものはありません。たとえば、次のクラスが有効になります。
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, "")
}
私がそれを行うことができるという事実は、私が持っている唯一の情報がA
'sの与えられたサブクラスのものであるというオブジェクトのコピーをしている場合、それを引き起こします:
// type error: Seq[A] is not a Seq[CA]!
def createCopies[CA <: A](seq: Seq[CA]): Seq[CA] = seq.map(_.copy(genNewId()))
私がそれを行うことができるより良い、タイプセーフな方法はありますか?
編集:可能であれば、抽象クラスの任意の深い階層を作成する機能を維持したいと思います。つまり、前の例では、を拡張する抽象クラスを作成してから、の具象サブクラスの作成に進むことができると期待しています。ただし、それによって問題が単純化される場合(抽象型の場合のように)、すでに具体的なクラスをさらに拡張する必要はありません。A2
A
A2