zoukankan      html  css  js  c++  java
  • 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群

    DT大数据梦工厂① :462923555
    DT大数据梦工厂②:437123764
    DT大数据梦工厂③ :418110145

    微信公众账号: DT_Spark
    王家林老师微信号: 18610086859
    王家林老师QQ: 1740415547
    王家林老师邮箱: 18610086859@126.com

    本视频由王家林老师, 亲自讲解, 完全通过代码实战把您带人大数据的时代.

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

      

  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/czh-liyu/p/4706050.html
Copyright © 2011-2022 走看看