W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
比較對象也是胖接口來的比較方便的一個應(yīng)用領(lǐng)域,當(dāng)你需要比較兩個有順序關(guān)系的對象時,如果只需要一個方法就可以知道需要比較的結(jié)果就非常便利。比如,你需要“小于”關(guān)系,你希望使用“< “比較就可以了,如果是“小于等于”,使用”<=”就可以。如果使用瘦接口來定義類,也許你只定義了一個<比較方法,那么如果需要小于等于,你可能需要使用(x<y)|| (x==y)。一個胖接口定義了所有可能的比較運(yùn)算符,使得你可以直接使用<=來書寫代碼。
但胖接口帶來的便利也是有代價的,回頭看看我們前面定義的Rational類;
如果我們需要定義比較操作,則需要定義如下代碼:
class Rational (n:Int, d:Int) {
...
def < (that:Rational) = this.numer * that.denom > that.numer * this.denom
def > (that:Rational) = that < this
def <=(that:Rational) = (this < that) || (this == that) def >=(that:Rational) = (this > that) || (this == that)
}
這個類定義了四個比較運(yùn)算符 < ,>,< =和>=。首先我們注意到后面三個比較運(yùn)算符,都是通過第一個比較運(yùn)算符來實(shí)現(xiàn)的。其次,我們也可以看到,后面三個比較操作對于任意對象都是適用的,和對象的類型無關(guān)。而需要實(shí)現(xiàn)這四個比較運(yùn)算的胖接口都要重復(fù)這些代碼。
Scala 對于比較這種常見的操作,提供了 Ordered Trait 定義,使用它,你可以把所有的比較運(yùn)算的代碼使用一個 compare 定義來替代。這個 ordered trait 可以讓需要實(shí)現(xiàn)比較運(yùn)算的類,通過和 Ordered 特質(zhì)“融合”,而只需實(shí)現(xiàn)一個 compare 方法即可。
因此我們可以修改前面的實(shí)現(xiàn)如下:
class Rational (n:Int, d:Int) extends Ordered[Rational]{
...
override def compare (that:Rational)=
(this.numer*that.denom)-(that.numer*that.denom)
}
要注意兩點(diǎn),一是 Ordered 需要指明類型參數(shù) Ordered[T] ,類型參數(shù)我們將在后面介紹,這里只需要知道添加所需比較類型的類名稱,本例為 Rational,此外,需要使用 compare 方法。 它比較有序?qū)ο螅?0,表示兩個對象相同,>0表示前面大于后面對象,<0表示前面小于后面對象。
下面為測試結(jié)果:
scala> class Rational (n:Int, d:Int) extends Ordered[Rational]{
| require(d!=0)
| private val g =gcd (n.abs,d.abs)
| val numer =n/g
| val denom =d/g
| override def toString = numer + "/" +denom
| def +(that:Rational) =
| new Rational(
| numer * that.denom + that.numer* denom,
| denom * that.denom
| )
| def * (that:Rational) =
| new Rational( numer * that.numer, denom * that.denom)
| def this(n:Int) = this(n,1)
| private def gcd(a:Int,b:Int):Int =
| if(b==0) a else gcd(b, a % b)
|
| override def compare (that:Rational)=
| (this.numer*that.denom)-(that.numer*that.denom)
|
| }
defined class Rational
scala> val half =new Rational(1,2)
half: Rational = 1/2
scala> val third=new Rational(1,3)
third: Rational = 1/3
scala> half < third res0: Boolean = false
scala> half >= third
res1: Boolean = true
因此,你在需要實(shí)現(xiàn)比較對象時,首先需要考慮 Ordered Trait,看看這個 Trait 能否滿足要求,然后通過和這個 Trait “混合”就可以很方便的實(shí)現(xiàn)對象之間的比較。
此外要注意 Ordered Trait 沒有定義equal 方法,因?yàn)槿绻枰x equal 方法,那么需要檢查傳入?yún)?shù)的類型,Ordered Trait 無法實(shí)現(xiàn),因此你如果需要==比較運(yùn)算符,需要另外定義。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: