Scala 深刻淺出實戰經典 第49課 Scala中Variance代碼實戰(協變)

王家林親授《DT大數據夢工廠》大數據實戰視頻 Scala 深刻淺出實戰經典(1-64講)完整視頻、PPT、代碼下載:
百度雲盤:http://pan.baidu.com/s/1c0noOt6
騰訊微雲:http://url.cn/TnGbdC
360雲盤:http://yunpan.cn/cQ4c2UALDjSKy 訪問密碼 45e2
技術愛好者尤爲是大數據愛好者 能夠加DT大數據夢工廠的qq羣java

DT大數據夢工廠① :462923555
DT大數據夢工廠②:437123764
DT大數據夢工廠③ :418110145微信

微信公衆帳號: DT_Spark
王家林老師微信號: 18610086859
王家林老師QQ: 1740415547
王家林老師郵箱: 18610086859@126.comoop

本視頻由王家林老師, 親自講解, 徹底經過代碼實戰把您帶人大數據的時代.大數據

package com.parllay.scala.oop

/**
 * Created by richard on 15-8-3.
 * 第49課 Scala中Variance代碼實戰(協變)
 *
 * 對於一個帶類型參數的類型,好比 List[T],若是對A及其子類型B,
 * 知足 List[B]也符合 List[A]的子類型,那麼就稱爲covariance(協變),
 * 若是 List[A]是 List[B]的子類型,即與原來的父子關係正相反,
 * 則稱爲contravariance(逆變)

協變:

 _____               _____________
|     |             |             |
|  A  |             |  List[ A ]  |
|_____|             |_____________|
   ^                       ^
   |                       |
 _____               _____________
|     |             |             |
|  B  |             |  List[ B ]  |
|_____|             |_____________|
逆變:

 _____               _____________
|     |             |             |
|  A  |             |  List[ B ]  |
|_____|             |_____________|
   ^                       ^
   |                       |
 _____               _____________
|     |             |             |
|  B  |             |  List[ A ]  |
|_____|             |_____________|
若是一個類型支持協變或逆變,則稱這個類型爲variance(翻譯爲可變的或變型),
不然稱爲invariant(不可變的)

在Java裏,泛型類型都是invariant,好比 List<String> 並非 List<Object> 的子類型。
Java並不支持聲明點變型(declaration-site variance,即在定義一個類型時聲明它爲可變型,
也稱definition-site),而scala支持,能夠在定義類型時聲明(用加號表示爲協變,減號表示逆變),如:

trait List[+T] // 在類型定義時(declaration-site)聲明爲協變
這樣會把List[String]做爲List[Any]的子類型。

不過Java支持使用點變型(use-site variance),所謂「使用點「,也就是在聲明變量時:

List<? extends Object> list = new ArrayList<String>();

scala> val a : List[_ <: Any] = List[String]("A")
a: List[_] = List(A)
要注意variance並不會被繼承,父類聲明爲variance,子類若是想要保持,仍須要聲明:

scala> trait A[+T]

scala> class C[T] extends A[T]  // C是invariant的

scala> class X; class Y extends X;

scala> val t:C[X] = new C[Y]
<console>:11: error: type mismatch;
 found   : C[Y]
 required: C[X]
Note: Y <: X, but class C is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
必須也對C聲明爲協變的才行:

scala> class C[+T] extends A[T]

scala> val t:C[X] = new C[Y]
t: C[X] = C@6a079142

 */
trait A[+T]
class C[+T] extends A[T]  // C是invariant的
class Person1; class Student1 extends Person1


object Variance {

  def main(args: Array[String]) {
    //這樣是報錯的, 好比把C[T] 申明爲C[+T], 而後下面的語句就不會報錯了.
    val t: C[Person1] = new C[Student1]
  }

}
相關文章
相關標籤/搜索