MICKEYSTUDY 2019-10-10
类型关系
Scala 支持在泛型类上使用型变注释,用来表示复杂类型、组合类型的子类型关系间的相关性
协变 +T,变化方向相同,通常用在生产
假设A extends T, 对于Clazz[+T],则Clazz[A]也可看做Clazz[T]
// 官网示例
abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal由于 Scala 标准库中不可变 List 的定义为 List[+A],因此 List[Cat] 是 List[Animal] 的子类型, List[Dog] 也是 List[Animal] 的子类型,所以可直接将他们当作 List[Animal] 使用。
// 官网示例
object CovarianceTest extends App {
def printAnimalNames(animals: List[Animal]): Unit = {
animals.foreach { animal =>
println(animal.name)
}
}
val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))
printAnimalNames(cats)
// Whiskers
// Tom
printAnimalNames(dogs)
// Fido
// Rex
}逆变 -T,变化方向相反,通常用在消费
假设A extends T, 对于Clazz[-T],则Clazz[T]也可看做Clazz[A]
// 官网示例
abstract class Printer[-A] {
def print(value: A): Unit
}
class AnimalPrinter extends Printer[Animal] {
def print(animal: Animal): Unit =
println("The animal's name is: " + animal.name)
}
class CatPrinter extends Printer[Cat] {
def print(cat: Cat): Unit =
println("The cat's name is: " + cat.name)
}
object ContravarianceTest extends App {
val myCat: Cat = Cat("Boots")
def printMyCat(printer: Printer[Cat]): Unit = {
printer.print(myCat)
}
val catPrinter: Printer[Cat] = new CatPrinter
val animalPrinter: Printer[Animal] = new AnimalPrinter
printMyCat(catPrinter)
printMyCat(animalPrinter) // 将 Printer[Animal] 当作 Printer[Cat] 使用
}