2017-01-20 21 views
0

Я пытаюсь перечислить функции, которые анализируют данные (теги ID3). На данный момент у меня есть перечисление, который выглядит следующим образом:Как создать enum с наследованием?

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?

Я хочу, чтобы иметь возможность использовать Id3Layout класс вместо жесткого кодирования Id3V1Layout или Id3V2Layout.

Но перечисления не могут наследовать от абстрактных классов, и я не могу определить конструктор или атрибуты в интерфейсе.

Как я могу определить разные элементы с разными параметрами, используя один общий класс, который имеет атрибуты (ы), которые имеют оба перечисления?

+0

Я не уверен, если я полностью понимаю, что вы хотите, но слово «с помощью» в «... используя один общий класс ...» может быть намек, что вы на самом деле хотите композицию вместо наследования - что вы можете использовать экземпляры общего класса, который содержит общие атрибуты и методы в разных перечислениях. При необходимости полиморфизм может быть достигнут путем разоблачения методов через интерфейс, реализуемый перечислениями. – 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