隐式转换: implicit
目的:偷偷摸摸/隐式/悄无声息的对方法进行了增强
如何对一个已经存在的类添加一个新方法或者增强方法的功能
Java:动态代理
Scala:隐式转换
双刃剑:有好有坏,看你自己怎么使用了。
案例1:
object ImplicitApp extends App {
//定义隐式转换函数即可
implicit def man2superman(man:Man):Superman = new Superman(man.name)
val man = new Man("PK")
man.fly() //如果把implicit这句话注释掉的话就只有一个eat()方法,但是现在有了隐式转换以后就有了fly()这个方法。
}
class Man(val name:String) {
def eat(): Unit = {
println(s"man[ $name ] eat .......")
}
}
class Superman(val name:String) {
def fly(): Unit = {
println(s"superman[ $name ] fly ..... ")
}
}
案例2:
File中没有read方法
==> 通过隐式转换,将File类增强,使得有read方法
object ImplicitApp extends App {
//普通的打开文件写法:
val file = new File("")
file.read //但是这里是没有read方法的。
//用隐式转换的方式:
implicit def file2RichFile(file: File): RichFile = new RichFile(file)
val file = new File("Users/rocky/imooc/hello.txt")
val txt = file.read() //这时就有read方法了。
println(txt)
}
class RichFile(val file:File) {
def read()= {
scala.io.Source.fromFile(file.getPath).mkString
}
}
在工作中,肯定会把所有的都封装在一个文件里,用到的时候import导入进来这个包就可以了
例如:
单独一个文件
object ImplicitAspect {
implicit def man2superman(man:Man):Superman = new Superman(man.name)
implicit def file2RichFile(file: File): RichFile = new RichFile(file)
}
另一个文件:
import ImplictiAspect._ // 引入进来就可以使用了
object ImplicitApp extends App {
val man = new Man("PK")
man.fly()
val file = new File("Users/rocky/imooc/hello.txt")
val txt = file.read()
println(txt)
}
隐式参数:
指的是在函数或方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数
object ImplicitApp extends App {
def testParam(implicit name:String): Unit = {
println(name + "~~~~~~~~~~~~")
}
测试1:
testParam //报错
testParam("zhangsan") //把zhangsan传了进去,做了一个隐式转换。
测试2:
implicit val name = "implicit_name"
testParam //implicit_name~~~~~~~~~~
testParam("PK") //PK~~~~~~~~~~~
测试3:
implicit val s1 = "s1"
implicit val s2 = "s2"
testParam // 报错,因为不知道传哪个,编译器识别不出来。
}
隐式类:
对类添加implicit 限定的类,其作用主要是对类的加强。
object ImplicitClassApp extends App {
implicit class Calculator(x:Int) {
def add(a:Int) = a + x
}
println(1.add(3)) //正常是没有add这个方法的。现在对Int类型都有这add这个方法了。
println("12".add(3)) //报错的,因为并没有对String类型的加add这个方法。
}