一、泛型的操作
- 背景
scala的类和方法
1、函数都可以是泛型,在Spark源码中可以到处看到类和方法的类型,在实际的实例化的时候指定具体的类型
2、 例如Spark的最核心、最基础、最重要的抽象数据结构RDD里面关于RDD的类的定义是泛型,RDD几乎所有的方法的定义也都是泛型,之所以这么做
3、是以为内RDD会派生很多的子类,通过子类适配了各种不同的数据源以及业务逻辑
class Animal[T](val species: T) {
def getAnimal(specie: T)= println(species)
}
通过主函数的调用泛型类并打印出结果。
def main(args: Array[String]): Unit = {
println( new Animal[String]("wenxuan").getAnimal("123"))
}
二、边界限定
- 背景
1、关于对类型边界的限定,分为上边界和下边界
2、上边界:表达了泛型的类型必须是某种类型或者某种子类,语法为<:,这里的一个新的现象是对类型进行限定
3、下边界:表达了泛型的类型必须是某种类型或者某种类的父类,语法为>:;
定义基础的实现类
class Person(val name: String) {
def talk(person: Person): Unit = {
println(this.name + ":" + person.name)
}
}
class Worker(name: String) extends Person(name)
定义泛型类
class Club[T <% Person](p1: T, p2: T) { // <% 隐士转换成person
def comunicte = p1.talk(p2)
}
实例化类,实例化泛型类
val p = new Person("Scala")
val w = new Worker("Spark")
new Club[Person](w, dog).comunicte
三、View Bounds的视图界定
- 背景:
1、Viwe Bounds,可以进行某种神秘的转换,把你的类型可以在没有只觉得情况下转成为目标类型,其实你可以认为View Bounds是上边界和下边界的加强补充版本
2、例如在SparkcContext这个Spark的核心类中由T<% Writable方式的代码,这个代码所表达的T必须是Writable类型的,但是T由没有直接继承自Writable的接口,此时就需要通过“implicait的方式”来实现这个功能
定义功能类
class Dog(val name: String)
class Person(val name: String) {
def talk(person: Person): Unit = {
println(this.name + ":" + person.name)
}
}
定义泛型类
class Club[T <% Person](p2: T, p1: T) { //将T <% 隐士转换成person
def comunicte = p1.talk(p2)
}
主函数的实现
def main(args: Array[String]): Unit = {
implicit def dog2Person(dog: Dog) = new Person(dog.name) //把dog转换成person的隐士转换
val p = new Person("Scala")
val dog = new Dog("dahuang")
new Club[Person](w, p).comunicte
|
四、逆变和协变
- 背景
逆变和协变:-T和+T
1、对于一个带类型参数的类型,比如 List[T],如果对A及其子类型B,满足 List[B]也符合 List[A]的子类型,那么就称为covariance(协变)
父类可以参加即子类可以参加
2、如果 List[A]是 List[B]的子类型,即与原来的父子关系正相反,则称为contravariance(逆变),表达子类可以参加,即父类也可以参加
定义功能类
class Enginner
class Expert extends Enginner
class Meeting[-T]
定义实现函数
def partitcipateMeeting(meeting: Meeting[Enginner]): Unit = {//协变
def partitcipateMeeting(meeting: Meeting[Eexpert]): Unit = { //逆变
println("welcome")
}
主方法的调用
def main(args: Array[String]): Unit = {
val e = new Meeting[Enginner]
partitcipateMeeting(e)
val expert = new Meeting[Expert]
partitcipateMeeting(expert)
}
五、内容界定
- 背景:Context Bounds
T:Ordering这种语法必须能够编程Ordering[T] 这种方式
定义功能类
class Maximum[T: Ordering](val x: T, val y: T) {
def bigger(implicit ord: Ordering[T])={//将ord隐士转换成Ordering的类型
if(ord.compare(x,y) >0) x else y //传入的x,y来比较
}
}
主函数调用方法
def main(args: Array[String]): Unit = {
println(new Maximum(2,4).bigger)//可以任意类型
}