Scala学习之函数式对象

领略Scala的函数式对象,本章内容:
通过一个例子展现以内容
1、主构造器和辅构造器
2、重写toString方法和方法的重载
3、检查先决条件
4、自指向
5、隐式转换

呈现方式:
1、叙述表示
2、代码表示

叙述表示

基于下面事例代码的层次叙述。

  • 主构造器跟在类名后面,辅构造器展现方式如def this(n: Int) = this(n, 1)
  • 与Java类似,若无重写,解释器打印实例为Rational@a0b0f5
  • require()方法入参为以Boolean类型,如果传入是真,require()正常返回。反之抛出异常,阻止对象被构造。如果按照Java的模式来的话,这个方法应该位于构造器内,因为它是用来阻止对象创建的。
  • 自指向即this,与Java类似
  • 隐式转换,val r = new Rational(2,3)r*22*r是完全不同的,因为由于Scala的运算是调用方法,前者等于r.*2,而Int类中并没有入参为Raitonal类型的*运算方法。implicit def intToRational(x: Int): Rational = new Rational(x)implicit 关键字告诉Scala编译器,在一些情况下,将Int类型转换到Rational类型。隐式转换把库变得非常灵活和更加方便。不过正因为它强大而往往被误用。
/**
  * @author wangzha
  *         模拟计算器类
  */
class Rational(n: Int, d: Int) {
    require(d != 0)
    override def toString: String = numer + "/" + denom
    def add(that: Rational): Rational = new Rational(n* that.d+ d* that.n, d* that.d)      //编译错误 ①            
}

注意上面这一小段代码中,①处编译错误。这是由于尽管n,d入参都在add代码的可引用范围内,但是add方法仅能访问调用对象自身的值。当add实现访问n或者d的时候,编译器可以给你提供这些参数,即this.n或this.d(自引用)。但是that是无法访问的,因为它不是调用者。解决办法如下:

/**
  * @author wangzha
  *         模拟计算器类
  */
class Rational(n: Int, d: Int) {
    require(d != 0)
    override def toString: String = numer + "/" + denom
    val numer: Int = n 
    val denom: Int = d 
    def add(that: Rational): Rational = new Rational(numer * that.denom + denom * that.numer, denom * that.denom)           
}

代码表示

/**
  * @author wangzha
  *         模拟计算器类
  */
class Rational(n: Int, d: Int) {

    //3、检查先决条件
    require(d != 0)
    private val g = gcd(n.abs, d.abs)
    val numer: Int = n / g
    val denom: Int = d / g

    //2、重写toString方法
    override def toString: String = numer + "/" + denom

    //1、辅助构造器
    def this(n: Int) = this(n, 1)

    //4、自指向
    def add(that: Rational): Rational = new Rational(numer * that.denom + denom * that.numer, denom * that.denom)

    private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

    /**
      * 自定义操作符
      *
      * @param i
      * @return
      */
    def +(i: Int): Rational = {return new Rational(numer + i * denom, denom)}

    def +(rational: Rational): Rational = {return new Rational(numer * rational.denom + rational.numer * denom, denom * rational.denom)}

    //2、方法重载
    def -(rational: Rational): Rational = {return new Rational(numer * rational.denom - rational.numer * denom, denom * rational.denom)}

    def -(i: Int): Rational = {return new Rational(numer - i * denom, denom)}

    def *(rational: Rational): Rational = {return new Rational(numer * rational.numer, denom * rational.denom)}

    def *(i: Int): Rational = {return new Rational(numer * i, denom)}

    def /(rational: Rational): Rational = {return new Rational(numer * rational.denom, denom * rational.numer)}

    def /(i: Int): Rational = {return new Rational(numer, i * denom)}

    //5、隐式转换
    //implicit告诉编译器可以在一些情况下自动调用,要注意范围,要想Int被调用需要直接定义在解释器里
    implicit def intToRational(x: Int): Rational = new Rational(x)

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值