Scala: реализация метода с возвращаемым типом конкретного экземпляра
Мне нужен способ принудительного применения метода в абстрактном классе, чтобы иметь возвращаемый типбетон класс объекта он вызывается. Наиболее распространенным примером является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
Конкретные подклассы. Однако, если это упрощает проблему (как в случае с абстрактными типами), мне не нужно дополнительно расширять уже конкретные классы.