scala之隐式转换(类、方法、属性)
  TEZNKK3IfmPf 2023年11月12日 19 0

隐式转换可以再不需改任何代码的情况下,扩展某个类的功能。

隐式方法

例如java里面的String类就存在于jdk里面,除非你反编译String的类,然后新增一个方法,再达成jar包,放在引用里,才能使用你的新增方法,如果要拓展某类的方法(觉得不好用的)就会非常麻烦

需求:通过隐式转化为Int类型增加方法。

class MyRichInt(val self: Int) {
  def myMax(i: Int): Int = {
    if (self < i) i else self
  }

  def myMin(i: Int): Int = {
    if (self < i) self else i
  }
}

object TestImplicitFunction {

  implicit def convert(arg: Int): MyRichInt = {
    println("convert start")
    new MyRichInt(arg)
  }

  def main(args: Array[String]): Unit = {
    println(2.myMax(6))
  }
}
结果:
convert start
6

个人理解:2.myMax(6)

2是int 类型,有myMax方法吗??这个就是我们为Int新增的方法

注意object里声明了一个implicit def convert()方法,这个方法可以和其他普通方法一样被直接调用,例如

  def main(args: Array[String]): Unit = {
    println(convert(2))
    println(2.myMax(6))
  }

但是这个和隐式调用有什么关系吗?这个我是这么理解的,就是被标注了的这个方法,会在所有满足这个方法的条件下隐式的被调用,通俗的的说,这个方法会尝试和所有int类型的值进行匹配,看你需不需要这个方法

例如 val a =1  a是int类型,他就会匹配你需不需要,

你直接打个a它默认不需要

但是他会显示的把你看做是个a,但是隐式的把你看做convert(a)也就是说

表面上你是个a:int,但是实际上也是个convert(a) 也就是new MyRichInt(a) 类型是a:MyRichInt

所以你表面上有a:Int的方法,toString max abs 实际也有MyRichInt的myMax方法

demo2

class Dog(var name:String) {
    def say(): Unit ={
      println(name+"实际是条狗")
    }
}
class Person(var name:String) {
  def print(): Unit ={
    println(name+"表面是个人")
  }
}
object Person{

  implicit def convert(person: Person): Dog ={
    new Dog(person.name)
  }

  def main(args: Array[String]): Unit = {
    val chenchi: Person = new Person("xxx")
    chenchi.print()
    chenchi.say()
  }
}

本来new 了一个person结果能调用的狗的say方法。

隐式参数

普通方法或者函数可以通过implicit关键字声明隐式参数,调用该方法时,就可以传入该参数,编译器会再相应的作用域寻找符合条件的隐式值。

1)说明

(1)同一个作用域中,相同类型的隐式值只能有一个

(2)编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。

(3)隐式参数优先于默认参数

object TestImplicitParameter {

  implicit val str: String = "hello world!"

  def hello(implicit arg: String="good bye world!"): Unit = {
    println(arg)
  }

  def main(args: Array[String]): Unit = {
    hello
  }
}

个人理解:

声明了一个参数str :String是隐式值

被implicit修饰后还是有了两重身份,一重是全局变量,和普通一样,一重是隐式身份,哪里需要一个String的变量我就往哪里凑

例如我调用hello()方法 按道理应该要传一个参数,但是入参也是声明implicit,那么你不传,证明你缺少这个参数,我就自动隐式的补上。

隐式类

在Scala2.10后提供了隐式类,可以使用implicit声明类,隐式类的非常强大,同样可以扩展类的功能,在集合中隐式类会发挥重要的作用。

1)隐式类说明

(1)其所带的构造参数有且只能有一个

(2)隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的

object TestImplicitClass {

  implicit class MyRichInt(arg: Int) {

    def myMax(i: Int): Int = {
      if (arg < i) i else arg
    }

    def myMin(i: Int) = {
      if (arg < i) arg else i
    }
  }

  def main(args: Array[String]): Unit = {
    println(1.myMax(3))
  }
}

个人理解,

1.myMax(3) 和main方法同级的有个隐式类,这个隐式类的参数是arg:int,即对所有范围内的int参数,他都会给int参数一层隐式身份就是myRichInt。

所以1有了int的方法也有了myRichInt的方法

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2024年04月26日   48   0   0 面向对象Scala
  TEZNKK3IfmPf   2023年11月14日   25   0   0 Scala
  TEZNKK3IfmPf   2024年04月26日   31   0   0 htmlScala
  TEZNKK3IfmPf   2023年11月14日   20   0   0 Scala
  TEZNKK3IfmPf   2023年11月14日   15   0   0 参数Scala
  TEZNKK3IfmPf   2024年04月26日   36   0   0 Scalajavascript
  TEZNKK3IfmPf   2023年11月14日   17   0   0 Scala
  TEZNKK3IfmPf   2023年11月15日   17   0   0 Scalapython
  TEZNKK3IfmPf   2024年04月26日   45   0   0 Scala
  TEZNKK3IfmPf   2023年11月14日   22   0   0 Scala
  TEZNKK3IfmPf   2023年11月14日   19   0   0 Scala
  TEZNKK3IfmPf   2023年11月14日   77   0   0 Scala类型
  TEZNKK3IfmPf   2023年11月14日   27   0   0 Scala
TEZNKK3IfmPf