Scala高階編程之協變、逆變和不變

1、Scala的協變(+),逆變(-),協變covariant、逆變contravariant、不可變invariant

2、對於一個帶類型參數的類型,比如List[T],如果對A極其子類型B,滿足List[B]也符合List[A]的子類型,那麼久稱爲convariance(協變),如果List[A]是List[B]的子類型,即與原來的父子關係正相反,則稱爲contravariance(逆變).如果一個類型支持協變或逆變,則稱這個類型爲variance(翻譯爲可變的或變型),否則稱爲invariance(不可變的)

3、在java裏,泛型類型都是invariant, 比如List<String>並不是List<Object>的子類型。而scala支持,可以在定義類型時聲明(用加號表示爲協變,減號表示爲逆變),如 trait List【+T】 在類型定義時聲明爲協變這樣會把List[String]作爲List[Any]的子類型

在這裏引入關於這個符號的說明,在聲明Scala的泛型類型時,"+"表示協變,而"-"表示逆變

C[+T]:如果A是B的子類,那麼C[A]是C[B]的子類,稱爲協變

C[-T]: 如果A是B的子類,那麼C[B]是C[A]的子類,稱爲逆變

C[T]:  無論A和B是什麼關係,C[A]和C[B]沒有從屬關係,稱爲不變

示例如下:

 

package sparkgraphx

/**
 * Scala 協變、逆變
 */

object Demo {
  def main(args: Array[String]): Unit = {
    val t1: T1[Animal] = new T1[Dog]("汪汪汪") //ok
    println(t1)
    println()
    val t1Sub: T1[Dog] = new T1[Dog]("汪汪汪") //ok
    println(t1Sub)
    println()
    val t2: T2[Dog] = new T2[Dog]("汪汪汪") //ok
    println(t2)
    println()
    val t2Sub: T2[Dog] = new T2[Animal]("汪汪汪") //ok
    println(t2Sub)
    println()
    val t3: T3[Dog] = new T3[Dog]("汪汪汪") //ok
    println(t3)
    println()
    //error Error:(25, 26) type mismatch;
    // found   : sparkgraphx.T3[sparkgraphx.Animal]
    // required: sparkgraphx.T3[sparkgraphx.Dog]
    //Note: sparkgraphx.Animal >: sparkgraphx.Dog, but class T3 is invariant in type A.
    //You may wish to define A as -A instead. (SLS 4.5)
    //    val t3Sub: T3[Dog] = new T3[Animal]("汪汪汪")
    val t3Sub: T3[Dog] = new T3[Animal]("汪汪汪")
    println(t3Sub)
    println()

  }
}

class Animal

class Dog extends Animal

class T1[+A](sound: String) {
  override def toString: String = {
    sound
  }
}

class T2[-A](sound: String) {
  override def toString: String = {
    sound
  }
}

class T3[A](sound: String) {
  override def toString: String = {
    sound
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章