2017-01-20 40 views
0

我想枚舉解析數據(ID3標籤)的函數。目前,我有,看起來像這樣的枚舉:我應該如何設計一個帶繼承的枚舉?

enum Id3V1Layout { 
    HEADER(range(fromString(), 0, 3)), 
    TITLE(range(fromString(), 3, 33)), 
    ARTIST(range(fromString(), 33, 63)), 
    ALBUM(range(fromString(), 63, 93)), 
    YEAR(range(fromString(), 93, 97)), 
    /** length is 30 if zero bit != 0, else 28 */ 
    COMMENT(b -> range(fromString(), 97, b[125] == 0 ? 125 : 127).parse(b)), 
    TRACK(b -> b[125] == 0 ? range(v -> (int) v[0], 126, 127).parse(b) : -1), 
    GENRE(b -> b[127] < 0 ? null : Genre.values()[b[127]]); 

    public final Id3FieldParser parser; 

    static Id3FieldParser range(Id3FieldParser fn, int from, int to) { 
    return b -> fn.parse(Arrays.copyOfRange(b, from, to)); 
    } 

    static Id3FieldParser fromString() { 
    return bytes -> new String(bytes).trim(); 
    } 

    Id3V1Layout(Id3FieldParser parser) { 
    this.parser = parser; 
    } 
} 

(短解釋:每一個元素定義如何解析特定領域range是返回Id3FieldParser功能界面對象的方法)

現在我的問題是:既然我想稍後實現ID3v2佈局,我怎樣才能使Id3V1Layout具有與Id3V2Layout相同的構造函數和方法?

我希望能夠使用的,而不是硬編碼Id3V1LayoutId3V2LayoutId3Layout類。

但是枚舉不能從抽象類繼承,並且我無法在接口中定義構造函數或屬性。

那麼如何在使用一個具有屬性的枚舉類型的普通類時使用不同的參數定義不同的元素?

+0

我不知道我是否完全理解你想要什麼,但是「......使用一個普通類......」中的「using」這個詞可能暗示你實際上想要組合而不是繼承 - 這意味着您可以使用包含不同枚舉中常見屬性和方法的通用類的實例。如果需要,多態性可以通過由枚舉實現的接口公開方法來實現。 – Calculator

回答

1

尋找類似的東西?

class Id3Layout { 
    public interface ParseLayout { 
     Id3FieldParser getParser(); 
    } 
    private static Id3FieldParser range(Id3FieldParser fn, int from, int to) { 
     return b -> fn.parse(Arrays.copyOfRange(b, from, to)); 
    } 
    private static Id3FieldParser fromString() { 
     return bytes -> new String(bytes).trim(); 
    } 
    public enum Id3LayoutVersions { 
     V1(Id3V1Layout.values()), 
     V2(Id3V2Layout.values()); 

     private ParseLayout[] parseLayout; 
     private Id3LayoutVersions(ParseLayout[] pl) { 
      parseLayout = pl; 
     } 
     public ParseLayout[] getParseLayoutTokens() { return parseLayout; } 
    } 
    public enum Id3V1Layout implements ParseLayout { 
     HEADER(range(fromString(), 0, 3)), 
     ...; 
     private Id3FieldParser parser; 
     private Id3V1Layout(Id3FieldParser parser) { 
      this.parser = parser; 
     } 
     public Id3FieldParser getParser() { return parser; } 
    } 
    public enum Id3V2Layout implements ParseLayout { 
     HEADER(range(fromString(), 0, 3)), 
     ...; 
     private Id3FieldParser parser; 
     private Id3V2Layout(Id3FieldParser parser) { 
      this.parser = parser; 
     } 
     public Id3FieldParser getParser() { return parser; } 
    } 
+0

'range()'和'fromString()'需要是靜態的,因爲你不能對非靜態方法進行靜態引用。 – Calculator

+0

將這些方法更新爲靜態 – geneSummons