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
}
}