隐式参数:
1:关键字 implicit
2:作用域:先去找全局的,再找局部的
3:要找唯一能匹配上的,如果有多个条件都满足,就报错。
4:implicit 都需要在object里面去使用
隐士转换的发生的时机:
1)当一个对象去调用某个方法,但是这个对象并不具备这个方法。
a: Int RichInt (源码)
b:File RichFile (《快学scala》)
package day4 class MyFile(var pp:String) class MyRichFile(var p:String){ def path: Unit ={ println("ok:" + p) } } object implicit_2 { implicit def aa(a:MyFile)=new MyRichFile(a.pp) def main(args: Array[String]): Unit = { val file = new MyFile("yes") file.path } }
c:超人变身
package day4 class SuperMan (var name:String,var age:Int){ } class RichSuperMan(var name:String,var age:Int){ def fly: Unit ={ println(s"name = $name and age = $age") } } object Test{ implicit def rm(ss:SuperMan)=new RichSuperMan(ss.name,ss.age) def main(args: Array[String]): Unit = { val su = new SuperMan("zhangdan",55) su.fly } }
2)调用某个方法的时候,这个方法确实也存在,存入的参数类型不匹配。
a:北京售票厅
package day4.implicit_test2 class Test { } class Person(var name:String) class Student( name:String) extends Person(name:String) class Older(name :String) extends Person(name :String) object buyticket{ def butt(p:Student): Unit ={ println(p.name+"获得票了") } implicit def aa(x:Person)=new Student(x.name) def main(args: Array[String]): Unit = { val person = new Person("zhangsan") val student = new Student("xiao ming") val older = new Older("lao wang") // butt(person) butt(older) } }
3)视图边界
A <% B A必须是B的子类,如果不是,会触发隐士转换,转换成为B
package day4.implicit_test3 class Person(var name:String){ def sayHello: Unit ={ println(s"hello my name is $name") } def makeFriends(p:Person): Unit ={ sayHello p.sayHello } } class Student (name:String) extends Person(name :String) class Dog(var name:String) class MakeFriends [T <% Person]{ def paly(p1:Person,p2:Person): Unit ={ p1.makeFriends(p2) } } object Testtt{ implicit def dog2person(d:Dog):Person={ new Person(d.name) } def main(args: Array[String]): Unit = { val dds = new Person("dds") val ss = new Student("ss") val dogDog = new Dog("dog") val mak = new MakeFriends[Person] mak.paly(dds,ss) mak.paly(dds,dogDog) } }
package day4.implicit_test3 class Test1[T<:Comparable[T]] { def shuai(b1:T,b2:T): T ={ if (b1.compareTo(b2) < 0) b1 else b2 } } object TTT{ def main(args: Array[String]): Unit = { val zs = new Boy("zs",13) val ls = new Boy("ls",44) val p = new Test1[Boy] val boy = p.shuai(zs,ls) println(boy.name + "\t" + boy.value) } }
下界:
package day4.implicit_test3 class A (var name:String) class B (name:String) extends A( name:String) class C (name:String) extends B( name:String) class D (name:String)extends C( name:String) class GetIdCard { def getCard[T>:C](a:T){ println(" you get it") } } object ttt{ def main(args: Array[String]): Unit = { val card = new GetIdCard card.getCard[C](new C("myself")) } }
参加英雄联盟大赛 父类 -》 子类来了也可以
逆变:
上海大师赛(斯诺克的比赛) 子类(业余) --》 结果父类(丁俊晖)来了也可以。
package day4.implicit_test3 class A (var name:String) class B (name:String) extends A( name:String) class C (name:String) extends B( name:String) class D (name:String)extends C( name:String) class GetIdCard { def getCard[T>:C](a:T){ println(" you get it") } } object ttt{ def main(args: Array[String]): Unit = { val card = new GetIdCard card.getCard[C](new C("myself")) } }
package day4.implicit_test3 class A (var name:String) class B (name:String) extends A( name:String) class C (name:String) extends B( name:String) class D (name:String)extends C( name:String) class GetIdCard { def getCard[T>:C](a:T){ println(" you get it") } } object ttt{ def main(args: Array[String]): Unit = { val card = new GetIdCard card.getCard[C](new C("myself")) } }
package day4.implicit_test3 class A (var name:String) class B (name:String) extends A( name:String) class C (name:String) extends B( name:String) class D (name:String)extends C( name:String) class GetIdCard { def getCard[T>:C](a:T){ println(" you get it") } } object ttt{ def main(args: Array[String]): Unit = { val card = new GetIdCard card.getCard[C](new C("myself")) } }