小編給大家分享一下Scala中重載方法和隱式轉換怎么用,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
方法重載
回到Rational類上來。在最近一次改變之后,你可以在分數上用自然的風格做加法和乘法。但別忘了還有混合運算。例如,你不能把一個分數和一個整數乘在一起,因為‘*’的操作數只能是分數。所以對于分數r你不能寫r * 2。而必須寫成r * new Rational(2),看上去不漂亮。為了讓Rational用起來更方便,可以在類上增加能夠執行分數和整數之間的加法和乘法的新方法。既然已經到這里了,還可以再加上減法和除法。結果展示在代碼6.5中:
class Rational(n: Int, d: Int) { require(d != 0) private val g = gcd(n.abs, d.abs) val numer = n / g val denom = d / g def this(n: Int) = this(n, 1) def +(that: Rational): Rational = new Rational( numer * that.denom + that.numer * denom, denom * that.denom ) def +(i: Int): Rational = new Rational(numer + i * denom, denom) def -(that: Rational): Rational = new Rational( numer * that.denom - that.numer * denom, denom * that.denom ) def -(i: Int): Rational = new Rational(numer - i* denom, denom) def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom) def *(i: Int): Rational = new Rational(numer * i, denom) def /(that: Rational): Rational = new Rational(numer * that.denom, denom * that.numer) def /(i: Int): Rational = new Rational(numer, denom * i) override def toString = numer+"/"+denom private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b) }代碼 6.5 含有重載方法的Rational
現在每種數學方法都有兩個版本了:一個帶分數做參數,另一個帶整數?;蛘呖梢哉f,這些方法名都被重載:overload了,因為每個名字現在都被多個方法使用。例如,+這個名字被一個帶Rational的和另一個帶Int的方法使用。方法調用里,編譯器會揀出正確地匹配了參數類型的重載方法版本。例如,如果x.+(y)的參數y是Rational,編譯器就會揀帶有Rational參數的+方法來用。相反如果參數是整數,編譯器就會揀帶有Int參數的+方法做替代。如果你嘗試輸入:
scala> val x = new Rational(2, 3) x: Rational = 2/3 scala> x * x res37: Rational = 4/9 scala> x * 2 res38: Rational = 4/3
你會看到*方法的調用取決于每個例子里面右側操作數的類型。
注意
Scala分辨重載方法的過程與Java極為相似。任何情況下,被選中的重載版本都是***參數靜態類型的那個。有時如果不止一個***的版本;這種情況下編譯器會給你一個“參考模糊”的錯誤。
隱式轉換
現在你能寫r * 2了,或許你想交換操作數,就像2 * r這樣。不幸的是這樣做還不可以:
scala> 2 * r < console>:7: error: overloaded method value * with alternatives (Double)Double < and> (Float)Float < and> (Long)Long < and> (Int)Int < and> (Char)Int < and> (Short)Int < and> (Byte)Int cannot be applied to (Rational) val res2 = 2 * r ?
這里的問題是2 * r等同于2.*(r),因此這是在整數2上的方法調用。但Int類沒有帶Rational參數的乘法——沒辦法,因為類Rational不是Scala庫的標準類。
然而,Scala里有另外一種方法解決這個問題:你可以創建一個在需要的時候能自動把整數轉換為分數的隱式轉換。試著把這行代碼加入到解釋器:
scala> implicit def intToRational(x: Int) = new Rational(x)
這行代碼定義了從Int到Rational的轉換方法。方法前面的implicit修飾符告訴編譯器若干情況下自動調用它。定義了轉換之后,你現在可以重試之前失敗的例子了:
scala> val r = new Rational(2,3) r: Rational = 2/3 scala> 2 * r res0: Rational = 4/3
請注意隱式轉換要起作用,需要定義在作用范圍之內。如果你把隱式方法定義放在類Rational之內,它就不在解釋器的作用范圍?,F在,你要在解釋器內直接定義它。
正如你在這個例子中能領略到的,隱式轉換是把庫變得更靈活和更方便的非常強大的技術。因為他們如此強大,所以也很容易被誤用。第二十一章里你將發現隱式轉換的更多細節,包括在需要的時候把它們帶入作用范圍的方式。
看完了這篇文章,相信你對“Scala中重載方法和隱式轉換怎么用”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。