Предположим, у меня есть два класса A и B, причем B - подтип A. Это, очевидно, только часть более богатой иерархии типов, но я не думаю, что это актуально. Предположим, что A является корнем иерархии. Существует класс коллекции C, который отслеживает список A. Тем не менее, я хочу сделать C generic, так что можно создать экземпляр, который поддерживает только B и не будет принимать A.Дженерики в двунаправленной ассоциации
class A(val c: C[A]) {
c.addEntry(this)
}
class B(c: C[A]) extends A(c)
class C[T <: A]{
val entries = new ArrayBuffer[T]()
def addEntry(e: T) { entries += e }
}
object Generic {
def main(args : Array[String]) {
val c = new C[B]()
new B(c)
}
}
Код выше, очевидно, дают ошибку 'несоответствие типов: найдено: С [B] требуется C [A]' на new B(c)
линии.
Я не уверен, как это можно исправить. Невозможно сделать C ковариант в T (например, C[+T <: A]
), потому что ArrayBuffer невообразимо типизирован в T. Невозможно заставить конструктор B потребовать C [B], потому что C не может быть ковариантным.
Я здесь лаяю неправильное дерево? Я полный новичок Scala, поэтому любые идеи и советы могут быть полезными. Спасибо!
EDIT: В принципе, то, что я хотел бы иметь в том, что компилятор принимает и
val c = new C[B]()
new B(c)
и
val c = new C[A]()
new B(c)
но отвергнут
val c = new C[B]()
new A(c)
Это, вероятно, можно чтобы расслабить типизацию ArrayBuffer в C, чтобы быть A вместо T, и, следовательно, в addEntry, если это помогает.
Это действительно не так, потому что вы объясняете здесь причины, если C является ковариантным, но это не является строго требованием. Я не думаю, что есть необходимость сделать C [B] подтипом C [A]. – Verhoevenv
@Verhoevenv Если 'C [B]' не был подтипом 'C [A]', то как вы ожидаете, что 'new B (c)' будет работать, если 'c' типа' C [B] ' ? Сейчас я смотрю ваш пересмотр, и вы просите что-то невозможное. –