集合的协方差

因为集合在元素类型*中通常是协变的,所以可以在期望超类型的地方传递子类型的集合:

trait Animal { def name: String } 
case class Dog(name: String) extends Animal

object Animal {
  def printAnimalNames(animals: Seq[Animal]) = {
    animals.foreach(animal => println(animal.name))
  }
}

val myDogs: Seq[Dog] = Seq(Dog("Curly"), Dog("Larry"), Dog("Moe"))

Animal.printAnimalNames(myDogs)
// Curly
// Larry
// Moe

它可能看起来不像魔术,但是 Seq[Dog] 被一个期望 Seq[Animal] 的方法接受的事实是一个更高级的类型(这里:Seq)在其类型参数中是协变的整个概念。

*一个反例是标准库的 Set