【发布时间】:2011-06-05 15:57:49
【问题描述】:
假设我有两个类 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)
}
}
上面的代码显然在new B(c) 行上给出了错误“类型不匹配:找到 C[B],需要 C[A]”。
我不确定如何解决这个问题。不可能使 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 方法中也是如此。
【问题讨论】:
标签: generics inheritance scala bidirectional