将3个枚举概括为一种类型

joh*_*hni 24 java enums

我正在编写一个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
}
Run Code Online (Sandbox Code Playgroud)

在我的程序中的某些时候,无论文件类型如何,我都希望保留文件扩展名,这意味着我希望能够执行以下任何分配:

FileType fileExt = DocType.doc
FileType fileExt = ImageType.jpg
FileType fileExt = VideoType.mp4
Run Code Online (Sandbox Code Playgroud)

我怎样才能在Java中实现这种行为?我知道枚举不能扩展其他枚举,所以基本上优雅的解决方案是不可能的.

谢谢

Sle*_*idi 35

你可以宣布一个interface统治它们的人

interface FileType{
}

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

enum ImageType implements FileType{
 ....
}
Run Code Online (Sandbox Code Playgroud)

然后你可以声明类型的变量 FileType

FileType file = DocType.PDF;
Run Code Online (Sandbox Code Playgroud)

  • 您无法进行该分配,因为它们具有不同的类型.您需要编写一个从`String`转换为`FileType`的函数. (3认同)

Gri*_*aub 23

您可以将所有扩展名enumcontentType定义类型的字段放在一起:

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,
}
Run Code Online (Sandbox Code Playgroud)


Sha*_*haz 5

您可以做的一件事是拥有一个枚举implements接口。这是一些示例代码:

接口:

public abstract interface IFileType
{
    public abstract String getExtension();
}
Run Code Online (Sandbox Code Playgroud)

定义为图像类型:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

包含扩展的“文件”类:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一些粗略的代码,我只是为了展示一些东西而将其拼凑在一起。

我主要想展示如何使每个枚举都遵循一个接口,因为我认为这是解决您想要做的事情的一种方法。通过使枚举遵循接口,您可以很好地保证您可以通过继承获得函数名称相同、它们已被实现等。

我想展示的另一件事是枚举构造函数的想法。本例中的构造函数允许我们在枚举名称(可以是更易于理解的名称,如我用 所示DocType.POWERPOINT)与其扩展名之间创建映射。我相信任何看过代码的人都会知道 PPT == powerpoint,但只是想说明这样一个事实:如果需要的话,事物的名称可以更具描述性。另外,如果需要,您可以向构造函数添加其他参数,可以有多个构造函数等。

需要注意的一件重要事情是,您不能尝试从枚举本身外部创建新类型的枚举,如下所示:

ImageType tiff = new ImageType("tiff"); // 'Cannot instantiate the type ImageType.'
Run Code Online (Sandbox Code Playgroud)

我不会再详细介绍,因为这已经足够长了,但你不能这样做是件好事。枚举的构造函数只能在初始值列表(PDF、DOC 等)中“访问”。

最后,正如 David Z 在对另一个答案的评论中提到的那样,您可以MyFile实现工厂设计模式 - 但我将把它作为练习留给读者。

编辑:

当然,如果您需要知道您正在处理哪种文件类型,MyFile可以有一个类似 的函数getFileType,或者它可以有一系列函数isDocTypeisImageType如 、 等。所MyFile提供的并不完整,只是毕竟是一个例子。