重学scala:scala中的隐式转换和隐式参数

简介:

Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定将某种类型的对象转换成其他类型的对象,或是给一个类增加方法。通过这些功能,可以实现非常强大的功能。

1、隐式转换

隐式转换其核心就是定义一个使用 implicit 关键字修饰的方法,实现把一个原始类转换成目标类,这样你可以调用目标类中的方法,是不是很强大。隐式转换的方法需要定义在一个object中。

示例一:对第三方库类进行转化,让File类具备RichFile类中的read方法
import java.io.File

import scala.io.Source

object ExecFileDef {
  //定义一个隐式转换的方法,实现把File转换成RichFile
  implicit def file2RichFile(file: File) = new RichFile(file)
}

// 扩展file类
class RichFile(val file: File){
  //读取数据文件的方法
  def read():String={
    Source.fromFile(file).mkString
  }
}

object RichFile{
  def main(args: Array[String]): Unit = {
    //1、构建一个File对象
    val file = new File("F:\\acc.txt")

    //2、手动导入隐式转换
    import ExecFileDef.file2RichFile

    //此时的file已经被转化了, 可以使用read方法
    val data: String = file.read
    println(data)
  }
}
示例二:对自己定义的类使用隐式转换,普通人成为大佬
class AveragePerson(val name: String)


class Mogul(val name: String) {
  def come(): Unit = {
    println("大佬 "+ name + " 来了,掌声想起,自带光环,疯狂撒钱!")
  }
}


object TransformExec {

  implicit def AveragePerson2Mogul(averagePerson: AveragePerson): Mogul = {
    new Mogul(averagePerson.name)
  }

  def main(args: Array[String]): Unit = {
    val mogul = new AveragePerson("橙子园")
    mogul.come()
  }
}

结果:
在这里插入图片描述

示例三:一个类隐式转换具有相同方法的类的情况
class A
class B(a: A) {
  def readBook(): Unit ={
    println("B读书")
  }
}

class C(a: A){
  def readBook(): Unit ={
    println("C读书")
  }
  def writeBook(): Unit ={
    println("C写书")
  }
}

object BC{

  //创建一个类转换为2个类的隐式转换
  implicit def A2B(a: A)=new B(a)
  implicit def A2C(a: A)=new C(a)
}

object C{
  def main(args: Array[String]) {
    //导包
    //import BC._ 这会将AB类下的所有隐式转换导进来
    //import BC.A2B 只导入A类到B类的的隐式转换方法
    //import BC.A2C 只导入A类到C类的的隐式转换方法


    import BC._
    val a = new A

    //由于B类与C类中都有readBook(),只能导入其中一个,否则调用共同方法时代码报错
    //a.readBook()

    //A类可以执行C类中的writeBook()
    a.writeBook()

  }
}

结果:
在这里插入图片描述

2、隐式参数

它是指在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的用implicit修饰的参数,即隐式值,并注入参数。隐式参数也需要定义在一个object中。

示例:隐式参数的使用,老板给员工发钱
object Company{
  //注意:同一类型的隐式值只允许出现一次,否则会报错
  implicit val name: String = "橙子园"
  implicit val salary: Double = 100000.0
  //再次出现会报错
  //implicit  val zzz: String="橙子猿"

}

class Boss {
  //定义一个用implicit修饰的参数类型为String
  //注意参数匹配的类型,它需要的是String类型的隐式值
  def callName(implicit name: String): String={
    name
  }

  //定义一个用implicit修饰的参数,类型为Double
  //注意参数匹配的类型,它需要的是Double类型的隐式值
  def getMoney(implicit money: Double): String={
    money.toString
  }

}

object Boss extends App{
  //使用import导入定义好的隐式值,注意:必须先加载否则会报错
  import Company.name
  import Company.salary

  val boss = new Boss
  println(boss.callName + ":" + boss.getMoney)

}

结果:
在这里插入图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子园

期待你的鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值