隐式转换:简单的说,隐式转换就是当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转换提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。
概念:隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,可以提供优雅的类库,对类库的使用者隐匿掉那些枯草乏味的细节。
作用:隐式的对类的方法进行增强,丰富现有类库的功能
隐式转换的时机
当方法中的参数的类型与目标类型不一致时
当对象调用类中不存在的方法或成员时,编译器会自动将对象进行隐式转换
隐式转换有四种常见的使用场景:
将某一类型转换成预期类型
类型增强与扩展
模拟新的语法
类型类
使用方式:
1.将方法或变量标记为implicit
2.将方法的参数列表标记为implicit
3.将类标记为implicit
****加粗样式Scala支持两种形式的隐式转换:
隐式值:用于给方法提供参数
隐式视图:用于类型间转换或使针对某类型的方法能调用成功
****加粗样式隐式参数
scala中的隐式参数:(调用带有隐式参数的方法时,不传递参数默认使用引入隐式区域的相同类型的隐式参数)
/**
* scala中的隐式参数:(调用带有隐式参数的方法时,不传递参数默认使用引入隐式区域的相同类型的隐式参数)
*/
//申明一个隐式参数的可见区域(区域就是object或者是class)
object ImplictDemo06 {
//在ImplictDemo06隐式区域里面申明一个Int类型的隐式参数
implicit val age:Int = 17
//在同一个隐式区域内不能申明两个及以上的相同数据类型的隐式参数,否则会出现歧义
// implicit val sex:Int = 1
//但是可以再同一隐式区域内申明多个不同类型的隐式参数
implicit val name:String = "小三"
}
object ImplictDemo02 {
implicit val age1:Double = 18 // 不同的区域
}
//隐式参数测试
object ImplictDemo{
//获取普通名字的方法
def getName(name:String):Unit = {
println(s"name=$name")
}
//申明一个带隐式参数的方法
def getAge(implicit age:Int):Unit = {
println(s"age=$age")
}
//申明一个带隐式参数的方法
def getAge1(implicit age:Double):Unit = {
println(s"age=$age")
}
//带隐式参数的方法
def getLaoWangInfo(implicit name:String): Unit ={
println(s"my name is $name")
}
def main(args: Array[String]): Unit = {
// getName("老王") //调用普通方法
// getAge(18) //调用隐式参数的方法并传递值
// 调用隐式方法并使用隐式区域中的隐式参数作 为默认值
import com.qianfeng.day05.ImplictDemo06._ //引入隐式区域
getAge
import ImplictDemo02._
getAge1
}
}
隐式函数
scala中隐式视图:scala中隐式函数转换。隐式函数转换必须要引入隐式函数所在的区域
导入隐式函数区域,则隐式函数方法就可以直接通过调用该方法传入参数(对象)调用该隐式方法中所暴露对象的所有的属性和方法
import scala.io.Source
/**
* scala中隐式视图:scala中隐式函数转换。隐式函数转换必须要引入隐式函数所在的区域
*/
//读取文件类
class ReadFile{
def readFile(fileName:String):String = {
Source.fromFile(fileName).mkString //使用Source读取指定文件的内容
}
def prin(str:String) = {
println(str)
}
var name:String = "aaa"
}
//显示文件
class ShowFile{
def getFileName():String = {
"E:\\scaladata\\test.txt"
}
def getFileData(data:String):Unit = {
println(data)
}
}
class ShowFile1{
def getFileName1():String = {
"E:\\scaladata\\test.txt"
}
def getFileData1(data:String):Unit = {
println(data)
}
}
//隐式函数区域
object ImplictFunctionDemo08{
implicit def showFile2ReadFile(sf:ShowFile):ReadFile = {
new ReadFile //相当于该类被隐藏
// "aaaa"
}
}
//测试
object ImplictFunctionDemo07 {
def main(args: Array[String]): Unit = {
//调用普通方法
/*val rf = new ReadFile
val sf = new ShowFile
sf.getFileData(rf.readFile(sf.getFileName()))*/
//
//import ImplictFunctionDemo08._
val showFile = new ShowFile
val path = showFile.getFileName()
//使用隐式函数转换
val showfile = new ShowFile
val showfile1 = new ShowFile1
val filename = showFile.getFileName()
import ImplictFunctionDemo08._
val data = showFile.readFile(filename)
println(showFile.name)
/**
* 导入隐式函数区域,
* 则隐式函数方法就可以直接通过调用该方法传入参数(对象)调用该隐式方法中所暴露对象的所有的属性和方法
*/
}
}
隐式转换:实现方法的增强
柯里化和隐式值的使用
隐式转换
代理模式:代理一个实例,对实例做方法的增强
装饰模式:也叫包装模式。在IO流中,也是对实例的增强。
隐式转换就用到了装饰模式,装饰模式是显示的保证,隐式转换是对隐式的包装,此外隐式模式还用到了门面模式
implicit
门面模式,即不知道内部情况,拿来用即可