函数式对象之隐式转换

接着Rational这个例子,方法重载之后,我们可以写 r * 2了,或许可以交换一下操作数,就像2 * r这样。不幸的是这样做还不可以。这里的问题是2 * r等同于2.*(r),因此这是在整数2上的方法调用。但Int类没有带Rational参数的乘法。不过scala有另外的方法解决这个问题:可以创建在需要的时候自动把整数转换为有理数的隐式转换。如例:

package scalaTest
class Rational(n:Int,d:Int) {
    require(d != 0)
    private val g = gcd(n.abs,d.abs)
    val number:Int = n/g
    val demon:Int = d/g
    def this(n:Int) = this(n,1)
    override def toString = number + "/" + denom
    def +(that:Rational):Rational = {
        new Rational(number * that.denon + that.number * d,d * that.denom)
    }
    def +(i:Int):Rational = new Rational(number + i * denom ,denom)
    def *(that:Rational):Rational = {
        new Rational(number * that.number,denom * that.denom)
    }
    def *(i:Int):Rational = new Rational(number * i,denom)
    def lessThan(that:Rational) = {
        this.number * that.denom < that.number * this.denom
    }
    def max(that:Rational) = {
        if(this.lessThan(that)) that else this
    }
    private def gcd(a:Int,b:Int):Int = {
        if(b == 0) a else gcd(b,a % b)
    }
}

object M1 {
    //注意这里,隐式转换
    implicit def intToRational(x:Int) = new Rational(x)
    def main(args:Array[String]) {
        val r1 = new Rational(1,2)
        val r2 = new Rational(3,5)
        println(r1 + r2)
        println(r1 * r2)
        //看看这里
        println("测试隐式转换,5 * r1= " + 5 * r1)
    }
}

M1中添加了:implicit def intToRational(x:Int) = new Rational(x)这句代码,这行代码定义了从Int到Rational的转换方法。方法前面的implicit修饰符告诉编译器可以在一些情况下自动调用
请注意,要隐式转换起作用,需要定义在作用范围之内。如果你把隐式转换方法放在Rational定义之内,它就不在解释器的作用范围。我们将在后面介绍更多隐式转换的细节。


你可能感兴趣的:(scala)