18.3 类型变量界定
类型变量界定, 就类似于 Java 中的泛型上下限.
定义上界
需求: 一个函数接收两个参数, 返回较大的那个参数.
def max[T](a:T, b:T): T ={
if(a.compareTo(b) > 0) a else b // 错误: 因为scala并不能知道a中是否否有compareTo方法
}
我们可以给泛型T
添加一个上界: T <: Comparable[T]
def max[T <: Comparable[T]](a:T, b:T): T ={
if(a.compareTo(b) > 0) a else b // 正确: 要求传来的参数必须实现Comparable接口. T 必须是 Comparable 的子类型.
}
上界测试题:
object LowerBoundsDemo {
def main(args: Array[String]): Unit = {
biophony(Seq(new Bird, new Bird)) //?
biophony(Seq(new Animal, new Animal)) //?
biophony(Seq(new Animal, new Bird)) //?
biophony(Seq(new Earth, new Earth)) //?
}
def biophony[T <: Animal](things: Seq[T]) = things map (_.sound)
}
class Earth { //Earth 类
def sound() { //方法
println("hello !")
}
}
class Animal extends Earth {
override def sound() = { //重写了Earth的方法sound()
println("animal sound")
}
}
class Bird extends Animal {
override def sound() = { //将Animal的方法重写
print("bird sounds")
}
}
定义下界
def foo[T >: Int](a: T): Unit = {
}
下界练习题
class Earth { //Earth 类
def sound() { //方法
println("hello !")
}
}
class Animal extends Earth {
override def sound() = { //重写了Earth的方法sound()
println("animal sound")
}
}
class Bird extends Animal {
override def sound() = { //将Animal的方法重写
print("bird sounds")
}
}
class Moon
object LowerBoundsDemo {
def main(args: Array[String]): Unit = {
biophony(Seq(new Earth, new Earth)).map(_.sound())
biophony(Seq(new Animal, new Animal)).map(_.sound())
biophony(Seq(new Bird, new Bird)).map(_.sound())
val res = biophony(Seq(new Bird))
val res2 = biophony(Seq(new Object))
val res3 = biophony(Seq(new Moon))
println("\nres2=" + res2)
println("\nres3=" + res2)
}
def biophony[T >: Animal](things: Seq[T]) = things
}
总结:
在实际使用中,
- 一般上界用在函数的参数类型
- 下界用在函数的返回值类型