泛型类:
* 在类声明时,定义一些泛型类型,然后在类的内部,就可以使用这些泛型类型
* 在需要对类中的某些成员,如字段或方法中的参数进行统一的类型限制时,可以使用泛型类,使得程序具有更好的健壮性和稳定性
* 在使用类的时候,将类型参数替换为实际的类型即可。
* scala会自动推断泛型类型:给泛型类型的字段赋值时,scala会自动对类型进行推断
class F01[T1, T2, T3](val name: T1) {
var age: T2 = _
var sex: T3 = _
def say() = {
println(name)
}
}
object F01 {
def main(args: Array[String]): Unit = {
val p = new F01[String, Int, String]("张三")
p.age = 12
p.sex = "男"
p.say()
}
}
泛型函数:
* 与泛型类相似,在声明函数时指定泛型类型,然后在函数体内,多个变量或返回值,就可以使用泛型类型进行声明。
* 可以通过给使用了泛型类型的变量传递值,让scala自动推断泛型的实际类型,也可以在调用函数的时候,手动指定泛型的实际类型
class F02 {
def say[T1,T2,T3]( name:T1, age:T2):T3 = {
(name + "-" + age).asInstanceOf[T3]
}
}
object F02{
def main(args: Array[String]): Unit = {
val p = new F02
println(p.say("张三", 12))//scala会自动推断泛型的实际类型
println(p.say[String,Int,String]("李四", 14))//等同于上面
}
}
泛型类的上边界
<: 上边界定义的符号,[T <: C1],即泛型T只能是C1及其子类
class C1
class C1_1 extends C1
class C1_2 extends C1
class C2
class C2_1 extends C2
class C2_2 extends C2
//<: 上边界,即泛型T只能是C1及其子类
class F03[T <: C1] {
def say(p: T) = {
println(p.getClass)
}
}
object F03 {
def main(args: Array[String]): Unit = {
val c1 = new F03[C1]
val c1_1 = new C1_1
val c1_2 = new C1_2
c1.say(c1_1) //class fanxin.C1_1
c1.say(c1_2) //class fanxin.C1_2
val c1_3 = new F03[C1_1]
c1_3.say(c1_1) //class fanxin.C1_1
//以下代码错误,C1_2 不是 C1_1 的子类
// c1_3.say(c1_2)
//以下代码错误,C2 不是 C1的子类
// val c2 = new F03[C2]
}
}
泛型类的下边界
>: 下边界,T>: Adult,即泛型T只能取Adult类及其父类
class People
class Adult extends People
class Children extends Adult
//>: 下边界,即泛型T只能取Adult类及其父类
class F04[T >: Adult] {
def say(p: T) = {
println(p.getClass())
}
}
object F04 {
def main(args: Array[String]): Unit = {
val p = new F04[People]
p.say(new People)
val a = new F04[Adult]
p.say(new Adult)
//以下代码错误,Children是Adult的子类,超出下边界
// val c = new F04[Children]
}
}
协变与逆变
*协变,完美解决java中泛型的一些缺陷。
* 如Professor 是 Master 的子类,那么Card[Professor] 是不是Card[Master]的子类呢?
* 在java中不是,因此带来局限性。而scala的协变可以解决这一问题。其实就是泛型的上边界的加强版
* 与协变对应的是逆变,是泛型的下边界的加强版
class Master
class Professor extends Master
class Teacher extends Professor
class Student
//+T 协变,Professor 是 Master 的子类,那么Card[Professor] 就是 Card[Master] 的子类
class Card[+T]
//-T 逆变,规定了传入类型的下边界
class Card2[-T]
class F06 {
def enter(car: Card[Master]) = {
println("只有Master及其子类可以通过")
}
def enter2(car: Card2[Professor]) = {
println("只有Professor及其父类可以通过")
}
}
object F06 {
def main(args: Array[String]): Unit = {
val f = new F06
f.enter(new Card[Master])
f.enter(new Card[Professor])
//下行代码错误,Card[Student] 不是 Card[Master]的子类
// f.enter(new Card[Student])
f.enter2(new Card2[Professor])
f.enter2(new Card2[Master])
//下行代码错误,Card[Teacher] 不是 Card[Professor]的父类
// f.enter2(new Card2[Teacher])
}
}