Как конкатенировать последовательности в параметризованном классе?
Разбираюсь с полиморфизмом в Scala и не могу разобраться со следующим вопросом. Например есть некоторая иерархия классов:
class A
class B extends A
class C extends B
И есть некоторый класc Foo, конструктор которого принимает последовательность элементов и метод push который принимает новую последовательность элементов, конкатенирует ее с существующей последовательностью и возвращает новый Foo.
class Foo[T](a: Seq[T]) {
def push[T](b: Seq[T]): Foo[T] = {
new Foo(a ++ b) // тут получаю ошибку - type mismatch; found : Seq[Any]; required: Seq[T]
}
}
Но в моем случае это не работает и я не совсем понимаю почему Seq[T] кастуется в Seq[Any].
val foo = new Foo(Seq(new C, new C))
val bar = foo.push(Seq(new B, new B))
println(bar) // должен содержать [C, C, B, B]
Ответы (1 шт):
Вы перекрываете типовой параметр T в определении метода. T в push не имеет ничего общего с T в Foo, т.е. ваше определение приблизительно соответствует следующему.
class Foo[T](a: Seq[T]) {
def push[U](b: Seq[U]): Foo[U] = {
new Foo(a ++ b)
}
}
И так как в этом случае типы T и U никак не связаны, ближайшим общим предком для них будет Any.
Но эту связь можно задать, указав на то, что U является базовым для T (либо T и U - это один и тот же тип).
class Foo[T](a: Seq[T]) {
def push[U >: T](b: Seq[U]): Foo[U] = {
new Foo(a ++ b)
}
}