一、协变与逆变
1. 说明
- 协变:Son 是 Father 的子类,则 MyList[Son] 也作为 MyList[Father] 的 “子类”
- 逆变:Son 是 Father 的子类,则 MyList[Son] 作为 MyList[Father] 的 “父类”
- 不变:Son 是 Father 的子类,则 MyList[Father] 与 MyList[Son] 之间 “无父子关系“
2. 语法
// 不变
class MyList[T]{}
// 协变
// class MyList[+T]{}
// 逆变
// class MyList[-T]{}
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}
object TestGenerics {
def main(args: Array[String]): Unit = {
// 不变
var mylist1: MyList[Child] = new MyList[Child]
// var mylist2: MyList[Parent] = new MyList[Child] // error,无父子关系
// 协变
// var mylist1: MyList[Child] = new MyList[Child]
// var mylist2: MyList[Parent] = new MyList[Child]
// var mylist3: MyList[Child] = new MyList[SubChild]
// 逆变
// var mylist1: MyList[Child] = new MyList[Child]
// var mylist2: MyList[Child] = new MyList[SubChild] // error, 父子关系逆转
// var mylist3: MyList[SubChild] = new MyList[Child]
}
}
二、泛型上下限
泛型的上下限的作用是对传入的泛型进行限定
/**
[T <: Class]:泛型上限,类型 T 只能是 Class 或 Class 子类
[T >: Class]:泛型下限,类型 T 只能是 Class 或 Class 父类
*/
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}
object TestGenerics {
def main(args: Array[String]): Unit = {
def test[A <: Child](a: A) { // 类型只能是 Child及其子类
println(a.getClass.getName)
}
test[Child](new Child)
test[Child](new SubChild)
test[SubChild](new SubChild)
// test[Parent](new Child) // error
}
}
三、上下文限定
1. 说明
上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定 [A : Ordering]
之后,方法内无法使用隐式参数名调用隐式参数,需要通过 implicitly[Ordering[A]]
获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误
2. 语法
/**
def f[A: B](a: A) = println(a)
//等同于
def f[A](a: A)(implicit arg: B[A]) = println(a)
*/
object TestGenerics {
def main(args: Array[String]): Unit = {
def f[A: Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)
}
}