我需要一种方法来强制抽象类中的方法具有调用它的对象的具体类的返回类型。最常见的例子是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