泛型方法
把泛型定义到方法声明上,该方法参数由泛型由泛型决定
在调用时,明确类型
// 不采用泛型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: Tdef 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 }
```scalaobject Test {def main(args: Array[String]): Unit = {val child: Parent = new Childval 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 Personclass 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 }
```scaladef test[A <: Child](a: A): Unit = {println(a.getClass.getName)}test[Parent](new Child) // 报错,相当于把Child对象赋给了Parent类型的指针test[Child](new Child)test[Child](new subChild)
案例:列表排序去重
11224455667788
object Test02 {def main(args: Array[String]): Unit = {val file = Source.fromFile("./conf/test02")// 将数据按照空白字符切割 -> 数组类型 -> 列表类型val list1: List[String] = file.mkString.split("\\s+").toListval list2: List[Int] = list1.map(_.toInt)val set: Set[Int] = list2.toSetval list3: List[Int] = set.toList.sortedval bw = new BufferedWriter(new FileWriter("./conf/test03"))for(i <- list3) {bw.write(i.toString)bw.newLine()}bw.close()file.close()}}
