2011-08-16 57 views
4

我正在尋找在類實現Comparable的情況下compareTo()方法的定義的最佳實踐。因此,該方法的簽名必須是compareTo()的最佳實踐,當參數必須鍵入超類

public int compareTo(BaseClass arg) 

明顯的事情首先要做的就是檢查arg是一個instanceof這個類,如果是這樣,強制轉換爲類和成員進行比較。但是如果參數不是這個類的,而是其他一些也實現了BaseClass的類,那麼我該如何返回它的反射呢?

我知道,最好的做法是定義compareTo()只適用於它所屬的類,但是水位超過大壩。

+3

假設它是一個抽象類或接口,你爲什麼不只是讓'BaseClass'實現或擴展'Comparable'並利用實施細節班級的實施者? – BalusC

+0

你是否暗示BaseClass實現了compareTo(BaseClass),然後讓SubClass覆蓋它? – fishtoprecords

回答

3

報價:

讓我們過的compareTo合同的規定。第一個 規定說,如果在兩個對象參考之間反轉比較方向 ,則會發生預期的事情:如果第一個對象小於第二個對象,則第二個對象必須比第一個對象大 ;如果第一個對象等於第二個,則第二個必須等於第一個;如果第一個對象比第二個對象大 ,那麼第二個對象必須小於第一個對象。 第二條規定,如果一個對象大於一秒,而第二個大於三分之一,那麼第一個必須是 大於第三個。最後一條規定,所有與 比較相同的對象必須產生與任何其他對象相同的結果。

這三條規定的一個結果是,由acompareTo方法施加的相等性測試 必須遵守相同合同強加 的相同限制:自反性,對稱性和傳遞性。 因此,同樣的警告適用:除非您願意放棄面向對象抽象(Item 8)的 的好處,否則無法使用新的值組件擴展可實例化類,同時保留 compareTo協議。也適用相同的解決方法, 。如果要將值組件添加到實現了類比的類中,請不要擴展它;編寫一個不相關的類,其中包含第一個類的一個 實例。然後提供一個「查看」方法, 返回此實例。這使您可以實現任何compareTo 您喜歡的第二個類的方法,同時允許其客戶端 在需要時查看第二個類的實例作爲第一個類 的實例。

你應該做的@BalusC在他的評論中建議 - 使用基類的compareTo()方法對所有兒童班,或通過創建包含第一個實例無關類做上述建議的解決方法類。

2

你的錯誤是在你的問題。 您不必執行public int compareTo(BaseClass arg)。你必須實現'public int compareTo(YourClass arg)'。

在這種情況下,您不必使用instanceof並執行投射。這就是泛型被引入的原因:避免投射。

但是,如果你仍然想使用基類作爲參數至少做到以下幾點:

public class Test { 

} 

class SubTest <T extends Test> implements Comparable<T> { 
    @Override 
    public int compareTo(T o) { 
     // add your code with instanceof here 
     return 0; 
    } 
} 

至少這種方法要求的參數是你的基類的子類。從有效的Java,項目12

+0

我改變了基礎:class Test implements Comparable 它似乎更快樂。謝謝 – fishtoprecords

1

在這種情況下,反身意味着obj.compareTo(obj) == 0。這裏反思意味着什麼?

就compareTo(T o)指定的契約而言,如果涉及的類不能進行有意義的比較,那麼所需的語義將引發ClassCastException。

例如鑑於

class Fruit {/* ..*/ } 

class Apple extends Fruit {/* .. */ } 

@Ignore("bad OO") 
class GrannySmithApple extends Apple {/* .. */ } 

class Orange extends Fruit {/* ... */ } 

人們可以說,

Fruit a = new Apple(); 
    Fruit b = new GrannyApple(); 
    Fruit c = new Orange(); 

    // compare apples with apple? 
    // makes sense to expect an int value 
    r = a.compareTo(b) 

    // compare apples with oranges? 
    // makes sense to expect an exception 
    boolean excepted = false; 
    try { 
     c.compareTo(a); 
    } catch (ClassCastException e) { 
     excepted = true; 
    } finally { 
     assert excepted : "How can we compare apples with oranges?" 
    } 
+0

我的意思是a.compareTo(b)== - b.compareTo(a) 並且如果a.compareTo(b)> 0和b.compareTo(c)> 0,則 a.compareTo(c)> 0 – fishtoprecords

+0

這就是完整的自反性,傳遞性和對稱性。如果兩個子類不具有有意義的可比性,則上述不必成立(如果您實際上拋出所需的例外)。這就是我如何閱讀你的問題(你應該澄清,如果不是這樣的話)。 – alphazero