本篇作为scala快速入门系列的第三十五篇博客,为大家带来的是关于泛型的内容。
泛型
scala和Java一样,类和特质、方法都可以支持泛型。我们在学习集合的时候,一般都会涉及到泛型。
那如何自己定义泛型呢?
定义一个泛型方法
在scala中,使用方括号来定义类型参数。
语法
示例
- 用一个方法来获取任意类型数组的中间的元素 – 不考虑泛型直接实现(基于Array[Int]实现) – 加入泛型支持
参考代码
不考虑泛型的实现
加入泛型支持
泛型类
scala的类也可以定义泛型。接下来,我们来学习如何定义scala的泛型类。
语法
- 定义一个泛型类,直接在类名后面加上方括号,指定要使用的泛型参数
- 指定类对应的泛型参数后,就使用这些类型参数来定义变量了
示例
- 实现一个Pair泛型类
- Pair类包含两个字段,而且两个字段的类型不固定
- 创建不同类型泛型类对象,并打印
上下界
需求:
我们在定义方法/类的泛型时,限定必须从哪个类继承、或者必须是哪个类的父类。此时,就需要使用到上下界。
上界
使用<:
类型名表示给类型添加一个上界,表示泛型参数必须要从该类(或本身)继承。
语法
示例
- 定义一个Person类
- 定义一个Student类,继承Person类
- 定义一个demo泛型方法,该方法接收一个Array参数
- 定义一个demo泛型方法,该方法接收一个Array参数
- 测试调用demo,传入不同元素类型的Array
参数代码
下界
上界是要求必须是某个类的子类,或者必须从某个类继承,而下界是必须是某个类的父类(或本身)
语法
[NOTE]
- 如果类既有上界、又有下界。下界写在前面,上界写在后面
示例
- 定义一个Person类
- 定义一个Policeman类,继承Person类
- 定义一个Superman类,继承Policeman类
- 定义一个demo泛型方法,该方法接收一个Array参数
- 限定demo方法的Array元素类型只能是Person、Policeman
- 测试调用demo,传入不同元素类型的Array
参考代码1
参考代码2
代码语言:javascript复制object _04GenericType {
// 1. 定义类和子类
class Person
class Policeman extends Person
class Superman extends Policeman
// 2. 定义泛型方法,指定泛型的类型上下界
def demo[T >: Policeman <: Person](array: Array[T])={
println(array)
}
// 3. 调用demo方法,传入不同类型的数据进行测试
def main(args: Array[String]): Unit = {
demo(Array(new Person))
demo(Array(new Policeman))
// 编译报错:String类型并不是Person类型或者是它的子类
// demo(Array(new Superman))
}
}
协变、逆变、非变
spark的源代码中大量使用到了协变、逆变、非变,学习该知识点对我们将来阅读spark源代码很有帮助。
来看一个类型转换的问题:
如何让带有泛型的类支持类型转换呢?
非变
语法
- 默认泛型类是非变的
- 类型B是A的子类型,Pair[A]和Pair[B]没有任何从属关系
- Java是一样的
协变
语法
- 类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型
- 参数化类型的方向和类型的方向是一致的。
逆变
语法
- 类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
- 参数化类型的方向和类型的方向是相反的
示例
- 定义一个Super类、以及一个Sub类继承自Super类
- 使用协变、逆变、非变分别定义三个泛型类
- 分别创建泛型类来演示协变、逆变、非变
参考代码
本期的内容分享就到这里了,喜欢的小伙伴们记得点个赞,持续关注哟~下期为大家介绍的是scala的高阶函数,敬请期待٩(๑>◡<๑)۶