Подтвердить что ты не робот

Обобщите 3 перечисления в один тип

Я пишу программу Java, которая выполняет некоторые вычисления в файлах. Программа поддерживает 3 типа файлов (документы, изображения, видео) с каждым типом, допускающим только несколько форматов:

enum DocType {
    pdf, doc, docx, xls, xlsx, ppt, pptx
}

enum ImageType {
    bmp, jpg, png, gif, ico
}

enum VideoType {
    avi, mpg, mp4, wmv, mov, flv, swf, mkv
}

В какой-то момент в моей программе я хотел бы сохранить расширение файла независимо от типа файла, это означает, что я хотел бы выполнить любое из следующих назначений:

FileType fileExt = DocType.doc
FileType fileExt = ImageType.jpg
FileType fileExt = VideoType.mp4

Как я могу выполнить это поведение в Java? Я знаю, что перечисления не могут распространять другие перечисления, поэтому в основном элегантное решение невозможно.

Спасибо

4b9b3361

Ответ 1

Вы можете объявить interface, который определяет их все

interface FileType{
}

enum DocType implements FileType{
 PDF // yes, uppercase for constants
 ...
}

enum ImageType implements FileType{
 ....
}

И тогда вы можете объявлять переменные типа FileType

FileType file = DocType.PDF;

Ответ 2

Вы можете поместить все расширения в один и тот же enum с полем contentType, которое определяет тип:

enum FileType {
    PDF(ContentType.DOC),
    DOC(ContentType.DOC),
    // other doc types here ..

    BMP(ContentType.IMAGE),
    JPG(ContentType.IMAGE),
    // other image types here ..

    AVI(ContentType.VIDEO),
    MPG(ContentType.VIDEO),
    // other video types here ..
    ;

    ContentType contentType;

    FileType(ContentType contentType){
        this.contentType = contentType;
    }
}


enum ContentType{
    DOC, IMAGE, VIDEO,
}

Ответ 3

Одна вещь, которую вы можете сделать, - это enum implements интерфейс. Вот пример кода:

Интерфейс:

public abstract interface IFileType
{
    public abstract String getExtension();
}

Определено как тип изображения:

public enum ImageType implements IFileType
{
    BMP("bmp"),
    JPG("jpg"),
    PNG("png"),
    GIF("gif"),
    ICO("ico");

    private String extension;

    ImageType(String s)
    {
        extension= s;
    }

    @Override
    public String getExtension()
    {
        return extension;
    }
}

Другое определение как DocType (просто у вас есть пример с двумя типами файлов):

public enum DocType implements IFileType
{
    PDF("pdf"),
    DOC("doc"),
    DOCX("docx"),
    XLS("xls"),
    XLSX("xlsx"),
    POWERPOINT("ppt");

    private String extension;

    DocType(String s)
    {
        extension= s;
    }

    @Override
    public String getExtension()
    {
        return extension;
    }
}

Класс A 'File', чтобы включить расширение:

public class MyFile
{
    private IFileType fileType;

    public String getExtension()
    {
        return fileType.getExtension();
    }

    public void setType(IFileType t)
    {
        fileType = t;
    }

    public static void main(String[] args)
    {
        MyFile m = new MyFile();
        m.setType(ImageType.BMP);
        System.out.println(m.getExtension());
        m.setType(DocType.POWERPOINT);
        System.out.println(m.getExtension());
    }
}

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

В первую очередь я хотел показать, как вы можете сделать каждое перечисление привязанным к интерфейсу, так как я думаю, что один из способов решить то, что вы пытаетесь сделать. Сделав свои перечисления привязанными к интерфейсу, вы получите такую ​​хорошую гарантию, что получите с наследованием то, что имена (имена) функций одинаковы, что они были реализованы и т.д.

Еще одна вещь, которую я хотел показать, - это идея конструктора для перечисления. Конструктор в этом случае позволяет создать сопоставление между именем перечисления (которое может быть более понятным для человека именем, как я показываю с помощью DocType.POWERPOINT) и его расширением. Я уверен, что любой, кто смотрит на код, будет знать, что PPT == powerpoint, но просто хотел догнать домой тот факт, что имя вещи может быть более наглядным, если нужно. Кроме того, если необходимо, вы можете добавить дополнительные параметры в конструктор, вы можете иметь несколько конструкторов и т.д.

Важно отметить, что вы не можете попытаться создать новый тип перечисления вне самого enum, например:

ImageType tiff = new ImageType("tiff"); // 'Cannot instantiate the type ImageType.'

Я не буду вдаваться в подробности, потому что это уже достаточно долго, но хорошо, что вы не можете этого сделать. Конструктор для перечисления только "доступен" в списке начальных значений (PDF, DOC и т.д.).

И, наконец, как Дэвид Z упоминает в комментарии к другому ответу, вы могли бы MyFile реализовать шаблон дизайна factory, но я оставлю это как упражнение для читателя.

Изменить:

И, конечно, если вам нужно знать, с каким типом файлов вы имеете дело, MyFile может иметь такую ​​функцию, как getFileType, или может иметь ряд функций, таких как isDocType, isImageType и т.д. Предоставленный MyFile не должен быть полным, просто примером, в конце концов.