假设我有两个类 A 和 B,B 是 A 的子类型。显然,这只是更丰富的类型层次结构的一部分,但我认为这无关紧要。假设 A 是层次结构的根。有一个集合类 C 跟踪 A 的列表。但是,我想让 C 成为通用的,以便可以创建一个只保留 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)
}
}
上面的代码显然给出了错误 'type mismatch: found C[B], required C[A]' 就new B(c)
行了。
我不确定如何解决这个问题。不可能使 C 在 T 中协变(如C[+T <: A]
),因为 ArrayBuffer 在 T 中是非可变类型的。不可能使 B 的构造函数需要 C[B] 因为 C 不能是协变的。
我在这里吠错树了吗?我是一个完整的 Scala 新手,所以任何想法和提示都可能会有所帮助。谢谢!
编辑:基本上,我想要的是编译器同时接受
val c = new C[B]()
new B(c)
和
val c = new C[A]()
new B(c)
但会拒绝
val c = new C[B]()
new A(c)
可能可以将 C 中 ArrayBuffer 的类型放宽为 A 而不是 T,因此在 addEntry 方法中也是如此,如果这有帮助的话。