大数据系列修炼-Scala课程50
2016-09-25 20:07
260 查看
大数据系列修炼-Scala课程50
核心内容:
1、Scala中的Variance变化点
1>相同的子类关系叫做协变,相反的子类关系叫做逆变
2>逆变or协变指的是A[]这种泛型的数据类型,可变还是不可变指的仍是A[]这种泛型的数据类型
3>如果一个泛型类型A[]支持协变的或逆变的,则称这个范型类型A[]为可变的,否则为不可变的
4>在Java当中,泛型类型A[]都是不可变的,比如A[String]并不是A[Object]的子类型,在scala当中,虽然泛型类型默认是不可变的,
但是通过协变or逆变的语法机制,泛型类型A[]是可变的
5>可变的泛型类型并不会被子类继承,若父类声明为可变的,子类如果想保持可变类型,仍需要再次声明为可变类型
6>在声明scala的泛型类型时,+号表示协变,-号表示逆变:
C[+T]:如果A是B的子类,那么C[A]是C[B]的子类,即协变
C[-T]:如果A是B的子类,那么C[B]是C[A]的子类,即逆变
7>型变有两种类型,一种是逆变,一种是协变。
实例程序1:
实例程序2:
1>对于函数而言,函数的参数类型是逆变的或者不变的,而函数的返回值类型是协变的或不变的
2>对于函数而言,其参数就是逆变的逆变点,返回值就是协变的协变点
3>在scala当中,凡是具有apply方法的类的实例,就可以当做函数来使用。其中apply方法接受的参数就是函数的参数,而apply方法
的返回值就是函数的返回值
4>在定义scala类的时候,是否可以随便指定泛型类型为协变或者逆变呢?
答案是否定的,因为在类中定义的泛型类型可能在其方法中也会被使用到,所以必须考虑协变或者逆变的类型的限制,
scala规定,协变类型只能作为其方法的返回值类型,而逆变类型只能其作为方法的参数类型。
当然,假如协变类型或者逆变类型在其方法中根本就没有用到,那就无所谓了。
5>协变就是+号,用其父类;逆变就是-号,用其子类。
6>型变一直是用在类或方法上,不能用在对象上,对象是不能进行型变的,因为对象不存在泛型一说,而型变本身是基于泛型之上的。
实例程序1:
深度思考1:能说明问题的最完美的一个例子:
如有问题,欢迎留言!
核心内容:
1、Scala中的Variance变化点
1、Scala中可变的(Variance)、协变、逆变的相关概念 |
2>逆变or协变指的是A[]这种泛型的数据类型,可变还是不可变指的仍是A[]这种泛型的数据类型
3>如果一个泛型类型A[]支持协变的或逆变的,则称这个范型类型A[]为可变的,否则为不可变的
4>在Java当中,泛型类型A[]都是不可变的,比如A[String]并不是A[Object]的子类型,在scala当中,虽然泛型类型默认是不可变的,
但是通过协变or逆变的语法机制,泛型类型A[]是可变的
5>可变的泛型类型并不会被子类继承,若父类声明为可变的,子类如果想保持可变类型,仍需要再次声明为可变类型
6>在声明scala的泛型类型时,+号表示协变,-号表示逆变:
C[+T]:如果A是B的子类,那么C[A]是C[B]的子类,即协变
C[-T]:如果A是B的子类,那么C[B]是C[A]的子类,即逆变
7>型变有两种类型,一种是逆变,一种是协变。
实例程序1:
class A[+T] object App8 { def main(args:Array[String]):Unit= { val aa:A[String] = new A[String]() val bb:A[Any] = new A[String]() //相同的子类关系叫做协变 } }
实例程序2:
class A[-T] object App8 { def main(args:Array[String]):Unit= { val aa:A[String] = new A[String]() val bb:A[String] = new A[Any]() //相反的子类关系叫做逆变 } }
1、Scala中Variance变化点相关概念 |
2>对于函数而言,其参数就是逆变的逆变点,返回值就是协变的协变点
3>在scala当中,凡是具有apply方法的类的实例,就可以当做函数来使用。其中apply方法接受的参数就是函数的参数,而apply方法
的返回值就是函数的返回值
4>在定义scala类的时候,是否可以随便指定泛型类型为协变或者逆变呢?
答案是否定的,因为在类中定义的泛型类型可能在其方法中也会被使用到,所以必须考虑协变或者逆变的类型的限制,
scala规定,协变类型只能作为其方法的返回值类型,而逆变类型只能其作为方法的参数类型。
当然,假如协变类型或者逆变类型在其方法中根本就没有用到,那就无所谓了。
5>协变就是+号,用其父类;逆变就是-号,用其子类。
6>型变一直是用在类或方法上,不能用在对象上,对象是不能进行型变的,因为对象不存在泛型一说,而型变本身是基于泛型之上的。
实例程序1:
class Animal class Persion extends Animal class Student extends Persion class A[-T,-U] { def fun(first:T,second:U) = println(first+"\t"+second) //函数的参数类型只能是逆变的 } object App8 { def main(args:Array[String]):Unit= { val aa = new A[Persion,Persion]() aa.fun(new Persion, new Persion) //下面的这一行代码,可以从两个角度进行考虑: //1、从Scala的角度讲,first与second这两个函数参数被逆变所修饰,所以可以用其子类 //2、从Java的角度讲,Persion类既然是Student的子类,当然一个父类的引用可以指向其子类对象 //假设A的两个泛型T与U都是协变的,则first与second也是协变的,此时就不符合Java中多态的关系了,所以说,对于函数而言, //函数的参数类型只能被逆变修饰,或者为不变的 aa.fun(new Student(),new Student()) } }
深度思考1:能说明问题的最完美的一个例子:
trait A[-F,+T] { def apply(arg:F):T } object App2 { def main(args : Array[String]): Unit = { var aa: A[Any, String] = new A[Any,String]{ override def apply(arg: Any): String = "hello:" + arg } var aa2: A[String, Any] = aa var test: Any = aa2.apply("spark") } }
如有问题,欢迎留言!
相关文章推荐
- 大数据系列修炼-Scala课程32
- 大数据系列修炼-Scala课程46
- 大数据系列修炼-Scala课程63
- 大数据系列修炼-Scala课程09
- 大数据系列修炼-Scala课程35
- 大数据系列修炼-Scala课程16(1)
- 大数据系列修炼-Scala课程03
- 大数据系列修炼-Scala课程71
- 大数据系列修炼-Scala课程19
- 大数据系列修炼-Scala课程24(1)
- 大数据系列修炼-Scala课程58
- 大数据系列修炼-Scala课程11
- 大数据系列修炼-Scala课程64
- 大数据系列修炼-Scala课程02
- 大数据系列修炼-Scala课程08
- 大数据系列修炼-Scala课程21
- 大数据系列修炼-Scala课程48
- 大数据系列修炼-Scala课程68
- 大数据系列修炼-Scala课程52
- 大数据系列修炼-Scala课程67