泛型方法
把泛型定义到方法声明上,该方法参数由泛型由泛型决定
在调用时,明确类型
// 不采用泛型
def getMiddleElement(arr: Array[Any]) = arr(arr.length/2)
// 采用自定义泛型
def getMiddleElement[T](arr: Array[T]) = arr(arr.length /2)
def main(args: Array[String]): Unit = {
println(getMiddleElement(Array(1, 2, 3, 4, 5)))
println(getMiddleElement(Array("a", "b", "c")))
}
泛型类
把泛型定义到类的声明上,即该类中的成员的参数由泛型决定
在创建对象时,明确具体数据类型
class Pair[T](var a: T, var b: T)
def main(args: Array[String]) = {
val p1 = new Pair[Int](10, 20)
println(p1.a, p1.b)
}
泛型特质
在定义泛型特质的子类或者子类单例对象时,明确具体的数据类型
trait Logger[T] {
val a: T
def show(b:T)
}
object ConsoleLogger extends Logger[String] {
override val a: String = "xxx"
override def show(b: String): Unit = println(b)
}
def main(args:Array[String]): Unit = {
println(ConsoleLogger.a)
ConsoleLogger.show("abc")
}
协变 逆变 非变
- 非变:AB父子类关系,Pair[A] Pair[B]之间没有关系
- 协变:AB父子类关系,Pair[A] Pair[B]之间也是父子关系
- 逆变:AB父子类关系,Pair[A] Pair[B]之间是 子 父 关系 ```scala class Super class Sub extends Super class Temp1[T] class Temp2[+T] class Temp3[-T]
def main(args: Array[String]): Unit = { // 非变 val t1: Temp1[Sub] = new Temp1[Sub] val t2: Temp1[Super] = t1 //报错 非变 Super和Sub有父子类关系,但是Temp1[Super]和Temp1[Sub]没有关系
// 协变 val t3: Temp2[Sub] = new Temp2[Sub] val t4: Temp2[Super] = t3 // 协变
//逆变 val t5: Temp3[Sub] = new Temp3[Sub] val t6: Temp3[Super] = t5 // 报错
val t7: Temp3[Super] = new Temp3[Super] val t8: Temp3[Sub] = t7 }
```scala
object Test {
def main(args: Array[String]): Unit = {
val child: Parent = new Child
val childList: MyCollection[Parent] = new MyCollection[Child]
}
}
class Parent {}
class Child extends Parent {}
class SubChild extends Child{}
// 定义带泛型的集合类型
class MyCollection[+E] {} //协变 -E是逆变
泛型上下限
使用泛型时,如果要限定该泛型必须从哪个类继承,或者必须是哪个类的的父类,就需要使用泛型上下界
上界
[T <: Person] 只能是Person类型或者Person的子类
class Person
class Student extends Person
// 限定demo方法的Array元素类型只能是Person或者Person子类
def demo[T <: Person](arr: Array[T]): Unit = println(arr)
def main(args: Array[String]): Unit = {
demo(Array(new Person(), new Person()))
}
下界
必须是该类型或者该类型的父类型
- 同时有上下界时,[T >: 类型1 <: 类型2] 下界在前,上界在后 ```scala class Person
class Policeman extends Person
class Superman extends Policeman
def demoT >: Policeman = println(arr)
def main(arrs: Array[String]): Unit = { demo(Array(new Person())) demo(Array(new Policeman(), new Policeman())) demo(Arrau(new Superman())) //error }
```scala
def test[A <: Child](a: A): Unit = {
println(a.getClass.getName)
}
test[Parent](new Child) // 报错,相当于把Child对象赋给了Parent类型的指针
test[Child](new Child)
test[Child](new subChild)
案例:列表排序去重
11
22
44
55
66
77
88
object Test02 {
def main(args: Array[String]): Unit = {
val file = Source.fromFile("./conf/test02")
// 将数据按照空白字符切割 -> 数组类型 -> 列表类型
val list1: List[String] = file.mkString.split("\\s+").toList
val list2: List[Int] = list1.map(_.toInt)
val set: Set[Int] = list2.toSet
val list3: List[Int] = set.toList.sorted
val bw = new BufferedWriter(new FileWriter("./conf/test03"))
for(i <- list3) {
bw.write(i.toString)
bw.newLine()
}
bw.close()
file.close()
}
}