Reputation: 5568
I'm writing a Java program that does some calculations on files. The program supports 3 types of files (documents, images, videos) with each type allowing only few formats:
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
}
In some point in my program, I would like to hold the file extension regardless of the file type, this means that I'd like to be able to do any of the following assignments:
FileType fileExt = DocType.doc
FileType fileExt = ImageType.jpg
FileType fileExt = VideoType.mp4
How can I accomplish that behavior in Java? I know enums cannot extend other enums so basically the elegant solution is not possible.
Thanks
Upvotes: 23
Views: 5223
Reputation: 23329
You can declare an interface
that governs them all
interface FileType{
}
enum DocType implements FileType{
PDF // yes, uppercase for constants
...
}
enum ImageType implements FileType{
....
}
And then you can declare variables of type FileType
FileType file = DocType.PDF;
Upvotes: 35
Reputation: 1396
One thing you can do is have an enum implements
an interface. Here's some example code:
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;
}
}
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;
}
}
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());
}
}
This is somewhat rough code that I just slapped together for the purpose of showing a few things.
Primarily I wanted to show how you can make each enum adhere to an interface, since I think that's one way to solve what you're trying to do. By making your enums adhere to the interface you get that nice guarantee that you would get with inheritance that the function name(s) are the same, that they've been implemented, etc.
Another thing I wanted to show is the idea of a constructor for an enum. The constructor in this case allows us to create a mapping between the enumeration name (which can be a more human-readable name as I show with DocType.POWERPOINT
) and its extension. I'm sure anyone looking at the code would know that PPT == powerpoint, but just wanted to drive home the fact that the name of the thing can be more descriptive if need-be. Also if needed, you can add additional parameters to the constructor, you can have multiple constructors, etc.
One important thing to note is that you can't try to create a new type of the enum from outside the enum itself, like this:
ImageType tiff = new ImageType("tiff"); // 'Cannot instantiate the type ImageType.'
I won't go into further detail since this is already long enough, but it is a good thing that you can't do this. The constructor for an enum is only 'accessible' in the list of initial values (PDF,DOC, etc).
And finally, as David Z mentions in a comment to another answer, you could have MyFile
implement the factory design pattern - but I'll leave that as an exercise for the reader.
And of course, if you need to know what kind of file type you're dealing with, MyFile
can have a function like getFileType
, or it could have a series of functions like isDocType
, isImageType
, etc. The MyFile
provided isn't intended to be complete, just an example, after all.
Upvotes: 5
Reputation: 7986
You can put all extensions in the same enum
with a contentType
field that defines the type :
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,
}
Upvotes: 24