Обобщите 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? Я знаю, что перечисления не могут распространять другие перечисления, поэтому в основном элегантное решение невозможно.
Спасибо
Ответы
Ответ 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
не должен быть полным, просто примером, в конце концов.