泛型
<:
上边界限定
//只能饲养Dog或者Dog的子类 上边界限定
def keepDog[T<:Dog](t:T): Unit ={
println(t)
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("大黄狗")
val smallDog = new SmallDog("小狗狗")
keepDog(dog)
keepDog(smallDog)
keepDog(animal)//错误
}
>:
下边界限定
//只能饲养Dog或者Dog的父类 下边界限定 bug
def keepAnimal[T>:Dog](t:T){
println(t)
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("大黄狗")
val smallDog = new SmallDog("小狗狗")
keepAnimal(dog)
keepAnimal(animal)
keepAnimal(smallDog)//应该不成功 bug
}
//只允许是Dog或者Dog的父类
trait Keeper[T>:Dog] {
def keep(t:T): Unit ={
println(t)
}
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("大黄狗")
val smallDog = new SmallDog("小狗狗")
val k1 = new Keeper[Dog] {
override def keep(t: Dog): Unit = {
println(t)
}
}
val k2 = new Keeper[Animal] {
override def keep(t: Animal): Unit = {
println(t)
}
}
val k3 = new Keeper[SmallDog] {
override def keep(t: SmallDog): Unit = {
println(t)
}
}
}
<%
视图限定
例如T<%U
,要求上下文必须有一个`隐式转换能够将T转换为U类型
class SmallDog(name:String) extends Dog(name:String){
override def speek(): Unit = {
println(s"${name}小狗叫")
}
}
//可以将T看作是小狗
def keeperSmallDog[T <% SmallDog](t:T): Unit ={
t.speek()
}
object MyImplicitis {
//视图限定-->SmallDog
implicit def s2sd(name:String):SmallDog={
new SmallDog(name)
}
}
def main(args: Array[String]): Unit = {
keeperSmallDog(new SmallDog("小花花"))
import MyImplicitis._
keeperSmallDog("佩奇")
}
T:A
上下文绑定
表示上下文中环境必须存在这种隐式值A[T]
,否则程序编译出错。这样可以在上下文中还没有声明隐式值的时候确保方法能编译成功。
class Student[T] {
def showMessage(msg:T): Unit ={
msg match {
case name:String => println("name"+name)
case age:Int => println("age"+age)
case _ => println("不知道")
}
}
}
//上下文中必须得有Student[T]类型的隐式值
def sayInformation[T:Student](t:T): Unit ={
val stu = implicitly[Student[T]]//编译可以通过 如果没有[T:Student]编译错误 A:T确保方法内的implicitly不出错
stu.showMessage(t)
}
object MyImplicitis {
implicit val stu1=new Student[String]
implicit val stu2=new Student[Int]
}
+A协变
//管理T或者T的子类
trait Manager[+T] {
}
var m1 = new Manager[Animal] {}
var m2 = new Manager[Dog] {}
var m3 = new Manager[SmallDog] {}
m1=m2
m2=m3
m2=m1//错误
将子类的泛型引用赋值给父类。
-A逆变
//管理T或者T的父类
trait Manager[-T] {
}
var m1 = new Manager[Animal] {}
var m2 = new Manager[Dog] {}
var m3 = new Manager[SmallDog] {}
m1=m2//错误
m2=m3//错误
m2=m1
将父类的泛型引用赋值给子类
A不变
trait Manager[T] {
}
var m1 = new Manager[Animal] {}
var m2 = new Manager[Dog] {}
var m3 = new Manager[SmallDog] {}
m1=m2//错误
m2=m3//错误
m2=m1//错误