<%
这个符号有点像“<:”,但作用却完全不一样,类型上边界“<:”的意思有点像继承,A <: B 表示 A是B的子类;而A <% B的意思是“A可以转化为B”,这里可以不必强调A和B本身的关系,只要有一个从A到B的隐士转化即可。(注意:不必是隐士转换,因为可能是B类本身)下面我们看例子:
依然是上几篇文章中的那几个例子,有Earth、Anima、Bird三个类,三者之间的关系是:Bird继承于Animal,Animal继承于Earth
class Earth {
def sound(){
println("hello !")
}
}
class Animal extends Earth{
override def sound() ={
println("animal sound")
}
}
class Bird extends Animal{
override def sound()={
print("bird sounds")
}
}
然后我们定义一个函数:
def biophony[T <% Animal](things: T) = {
things.sound()
}
然后调用此方法:
biophony(new Earth)
输出结果:
它说得要一个从Earth到Animal的隐士转化,我们给它加上:
implicit def autoChange(things:Earth) = new Animal
运行:
成功!
我们讲到 A <% B,A和B可以没有父子关系,于是:
implicit def autoChange(things:String) = new Animal
def biophony[T <% Animal](things: T) = {
things.sound()
}
调用:
biophony(new String)
输出:
成功!
A<%B 原来可以当B 直接用!和传个B类型的参数没有区别,那么,我们真传一个B,还用类型转化吗?咱们把类型转化去掉。
def main(args: Array[String]) {
biophony(new Animal)
}
// implicit def autoChange(things:String) = new Animal
def biophony[T <% Animal](things: T) = {
things.sound()
}
运行,输出:
看来,如果直接传过需要转化成的参数类型,就不必做类型转化了。
A:B
上下文边界。在这里,不同于传参的A:B,在这里的意思是:必须存在一个“B[A]”的隐士值。
定义一个函数:
def biophony[T:Seq](things: T) = {
println("hello world")
}
如果直接调用:
def main(args: Array[String]) {
biophony(new Animal)
}
输出:
缺少B[A]的隐士参数,我们给它加上一个,然后调用:
implicit val b = Seq(new Animal)
biophony(new Animal)
成功!
"A <% B"和“A:B”都是和隐士转化有关,“A <% B”是有A到B的隐士转化,“A:B”是有B[A]的隐士参数。