先來(lái)看個(gè)demo
package com.peng.implicit_demo
import java.io.File
import scala.io.Source
object MyPredef {
implicit def file2RichFile(file: File): RichFile = new RichFile(file)
}
class RichFile(file: File) {
def read(): String = {
val fis = Source.fromFile(file)
fis.mkString
}
}
object RichFile {
def main(args: Array[String]): Unit = {
//1.構(gòu)建一個(gè)File對(duì)象
val file = new File("F:\\learnbigdata\\spark\\base\\testdata\\rawdata\\test.txt")
//2.手動(dòng)導(dǎo)入隱式轉(zhuǎn)換
import MyPredef.file2RichFile
//3.調(diào)用read方法
val data: String = file.read()
//4.打印結(jié)果
print(data)
}
}
從上面可以看到,在手動(dòng)導(dǎo)入隱式轉(zhuǎn)換后,file對(duì)象就有了read方法.在我看來(lái),其實(shí)在導(dǎo)入隱式轉(zhuǎn)換后,file對(duì)象就像被包裝類(lèi)包裝了一樣,獲得了增強(qiáng)的功能.
再來(lái)看看其他例子
package com.peng.implicit_demo
class Man(val name: String)
class SuperMan(val name: String) {
def heat(): Unit = print("超人打怪獸")
}
object SuperMan {
//隱式轉(zhuǎn)換
implicit def man2SuperMan(man: Man): SuperMan = new SuperMan(man.name)
def main(args: Array[String]): Unit = {
//實(shí)例化的時(shí)候,會(huì)把man注入man2SuperMan方法,得到增強(qiáng)后的實(shí)例
val hero = new Man("hero")
//man具備了SuperMan的方法
hero.heat
}
}
一個(gè)類(lèi)可以隱式轉(zhuǎn)換成具有相同方法的多個(gè)類(lèi)
package com.peng.implicit_demo
//一個(gè)類(lèi)隱式轉(zhuǎn)換成具有相同方法的多個(gè)類(lèi)
class C
class A(c: C) {
def readBook(): Unit = {
println("A說(shuō):好書(shū)好書(shū)...")
}
}
class B(c: C) {
def readBook(): Unit = {
println("B說(shuō):看不懂...")
}
def writeBook(): Unit = {
println("B說(shuō):不會(huì)寫(xiě)...")
}
}
object AB {
//創(chuàng)建一個(gè)類(lèi)轉(zhuǎn)換為2個(gè)類(lèi)的隱式轉(zhuǎn)換
implicit def C2A(c: C) = new A(c)
implicit def C2B(c: C) = new B(c)
}
object B {
def main(args: Array[String]) {
//導(dǎo)包
//1. import AB._ 會(huì)將AB類(lèi)下的所有隱式轉(zhuǎn)換導(dǎo)進(jìn)來(lái)
//2. import AB.C2A 只導(dǎo)入C類(lèi)到A類(lèi)的的隱式轉(zhuǎn)換方法
//3. import AB.C2B 只導(dǎo)入C類(lèi)到B類(lèi)的的隱式轉(zhuǎn)換方法
import AB._
val c = new C
//由于A類(lèi)與B類(lèi)中都有readBook(),只能導(dǎo)入其中一個(gè),否則調(diào)用共同方法時(shí)代碼報(bào)錯(cuò)
//c.readBook()
//C類(lèi)可以執(zhí)行B類(lèi)中的writeBook()
c.writeBook()
}
}
再來(lái)看看隱式參數(shù)轉(zhuǎn)換
package com.peng.implicit_demo
//隱式參數(shù)轉(zhuǎn)換
object Company {
//在object中定義隱式值
//注意:同一類(lèi)型的隱式值只允許出現(xiàn)一次,否則會(huì)報(bào)錯(cuò)
implicit val xxx = "zhangsan"
implicit val yyy = 10000.00
//implicit val zzz="lisi"
}
class Boss {
//定義一個(gè)用implicit修飾的參數(shù) 類(lèi)型為String
//注意參數(shù)匹配的類(lèi)型,它需要的是String類(lèi)型的隱式值
def callName(implicit name: String): String = {
name + " is coming !"
}
//定義一個(gè)用implicit修飾的參數(shù),類(lèi)型為Double
//注意參數(shù)匹配的類(lèi)型,它需要的是Double類(lèi)型的隱式值
def getMoney(implicit money: Double): String = {
" 當(dāng)月薪水:" + money
}
}
object Boss extends App {
//使用import導(dǎo)入定義好的隱式值,注意:必須先加載否則會(huì)報(bào)錯(cuò)
//這步操作,相當(dāng)于對(duì)callName和getMoney中的相同數(shù)據(jù)類(lèi)型的參數(shù)賦值
import Company.xxx
import Company.yyy
val boss = new Boss
println(boss.callName + boss.getMoney)
}