2013-01-08 14 views
0

我確定我以錯誤的方式解決這個問題,但是我想實現一個通用模式,其中某個類的實例表示一個集合的元素,並且該類的靜態方法將該集合的屬性作爲一個整體。我開始時只有一個班級,因此只有一個班級,但我想將其擴展到類似的集合,並使用適用於所有班級的通用方法。我正在考慮製作更多的類並讓它們都擴展相同的接口,但是這涉及到指定靜態方法的接口以及覆蓋它們的實現類。我知道抽象/重寫的靜態方法在Java中是不可能的,但我的代碼似乎需要他們

我認爲這個問題最好用羣論來解釋。對於那些不知道的人來說,一個組是一個數學對象,它包含一組元素,以及一個組合兩個元素並返回三分之一的組合操作(由*表示)。在其他條件中,必須有一個同一性元素e,使得a * e = a對於所有e,並且每個元素a必須具有ai,使得a * ai = e。最簡單的例子是整數,其中加法是組操作,身份元素是零,元素的逆是它的否定。如果我有一個操縱組的元素的泛型類,則有些情況下我需要知道組的標識元素是什麼。

所以我對組樣本界面可能是這樣的

public interface GroupElement { 

    public GroupElement operate(GroupElement element); 

    public static GroupElement identity(); 

} 

隨着整數實現是這個(忽略與先前存在的Integer類的明顯衝突):

public class Integer implements GroupElement { 

    private int i; 

    public Integer(int i) { 
     this.i = i; 
    } 

    public Integer operate(Integer other) { 
     return new Integer(i + other.i); 
    } 

    public static Integer identity() { 
     return new Integer(0); 
    } 
} 

然後通用檢查一個元素是否與另一個元素相反的對象:

public class InverseChecker <E implements GroupElement> { 

    public boolean isInverse(e element1, e element2) { 
     return element1.operate(element2).equals(E.identity()); 
    } 
} 

顯然上面的代碼有很多錯誤。第一個問題是我無法在接口中聲明靜態方法,即使我使用抽象父類,子類也無法重寫靜態方法。我可以使identity()方法是非靜態的,但是然後我會需要一個我不會總是擁有的實例。另外我也無法調用泛型類型E的靜態方法。我想我可以創建兩個接口,一個用於組,另一個用於組的元素,但是接下來看起來它會像InverseChecker對象那樣使代碼變得複雜(需要兩個類型參數,我必須重寫很多我的代碼,我不知道我將如何指定兩個接口之間的關係)。另外,我剛剛意識到,在輸入界面的方式時,您必須允許來自不同組的兩個元素之間的組操作,這是沒有意義的。那麼,實現這種結構的正確方法是什麼?

回答

1

這裏的解決方案 - 比如說 - 是以不同的方向看事物。該組應該是與其元素不同的對象,並且組對象應該有一個T operate(T, T)和一個T identity()方法。

換句話說,不要試圖擁有一個GroupElement接口並且有一個接口Group。此外,泛型可能會簡化一些事宜:Group<T>,其元素類型爲T

+0

是的,我想這是做這件事的唯一方法。但是,擁有「Group 」還是具有像GroupElement 一樣的GroupElement接口會更好?我正在考慮第二個,那麼所有在組上操作的泛型對象都可能具有泛型類型的'',並且方法將具有像'GroupElement '這樣的參數。雖然不完全確定它是否有效。 – JaredL

1

考慮第一句中的從句:「某個類的實例表示集合的元素」。它包含兩個問題相關的名詞,「元素」和「集合」。我最初的想法,隨着我對這個問題的更多瞭解而改變,將會有兩個類,Element和Set。我可能會重命名「Set」以避免與java.util.Set混淆 - 如果這是Group Theory,「Group」將是一個很好的選擇。

如果你這樣做,你可以在Element中設置元素相關的方法,在Set中設置相關的方法。兩者都可以被分類,正常覆蓋。

相關問題