Scala中的隱式轉(zhuǎn)換

先來(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)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容