【发布时间】:2016-11-01 08:27:57
【问题描述】:
我最近一直在尝试进一步加深对 Scala 的理解,但我无法真正弄清楚关于协变/逆变类型参数的一些事情。
假设我有一个名为Basket 的类,如下所示:
class Basket[+A <: Fruit](items: List[A]) {
// ...
def addAll[B >: A <: Fruit](newItems: List[B]): Basket[B] =
new Basket(items ++ newItems)
// ...
}
还有一些像这样的类:
trait Fruit
class Banana extends Fruit
class Orange extends Fruit
我确信这些断言是正确的:
Basket[Fruit]可以被实例化Basket[String]无法实例化(因为String不是Fruit的子类型)Basket[Banana]是Basket[Fruit]的子类型Basket[Orange]是Basket[Fruit]的子类型-
这段代码:
val bananaBasket: Basket[Banana] = new Basket(List(new Banana, new Banana)) bananaBasket.addAll(List(new Orange))
将返回Basket[Fruit]
-
这段代码:
val bananaBasket: Basket[Banana] = new Basket(List(new Banana, new Banana)) bananaBasket.addAll(List(new Banana))
将返回Basket[Banana]
我不明白B >: A 如何影响方法的返回类型。为什么当我添加Orange 时返回类型变为Basket[Fruit] 而当我添加Banana 时,它仍然是Basket[Banana] ?它是否寻找“最低”的普通超类型?
【问题讨论】:
-
当您尝试编译您的“断言”并查看其中哪些是正确的时,您发现了什么?
-
您还需要在
Basket.addAll方法(addAll[B >: A <: Fruit]...)中将Fruit作为参数B的上限添加。 -
所有断言都是正确的。我的问题确实不是很清楚。我会编辑它。
-
“它是否寻找“最低”的普通超类型? - 正是
-
@PeterNeyens 仅供参考,您知道为什么我们必须重复约束吗?
标签: scala inheritance types covariance