2016-01-08 7 views
24

ファイルの計算を行うJavaプログラムを作成しています。 プログラムはわずか数フォーマットできるように、各タイプを持つファイルの3種類(文書、画像、動画)をサポートします。私のプログラムの中でいくつかの点で3つの列挙型を1つのタイプに一般化する

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でその動作を達成することができますどのように?列挙型は他の列挙型を拡張できないので、基本的にエレガントな解決策は不可能です。

おかげ

+4

これらの列挙型を作成し、そのファイルタイプがドキュメント、ビデオ、またはイメージタイプかどうかを別の方法で追跡する方がよい場合があります。おそらく、この列挙型は、メンバが 'document、image、video、... 'である別のenum型のインスタンス変数を持つでしょう。 – user2357112

+2

スタイルのポイント - 'enum'値は' public static final'なので、他のコンパイル時定数と同じ名前にするべきです( 'UPPER_UNDERSCORE'の場合)。 –

+1

本当に列挙型が本当に必要かどうかという疑問が残っています。私が想像できるような使い方では、文字列のリストはうまくいくはずです。 – jpmc26

答えて

36

すべて

interface FileType{ 
} 

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

enum ImageType implements FileType{ 
.... 
} 

それらを支配するinterfaceを宣言することができます。そして、あなたはFileType

FileType file = DocType.PDF; 
+1

文字列として「pdf」があるとします。それを 'fileExt'変数にどのように代入しますか? (あなたはpdfが 'DocType'であることを知らない) – johni

+3

異なる型を持つので、その割り当てを行うことはできません。 'String'から' FileType'に変換する関数を書く必要があります。 – gardenhead

+1

@ johni 'インタフェースに' getFileExt(); 'メソッドを追加します。 –

23

あなたは同じ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, 
} 
+1

これは、サポートされていないファイルタイプが有用になった場合に、それを完全に拡張します。 'FileType'を' enum'ではなく 'class'にして、ファクトリ関数を提供してください。 –

+0

これは、Oracleチュートリアルに基づいたより正確なソリューションです。https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html また、ContentTypeに実際のファイル拡張子テキストを追加することもできます。 toString()は "DOC"ではなく ".doc"を表示します。 また、このアイデアを回して、ユースケースでより適切なものに応じてコンテンツタイプにファイルタイプを含めることもできます。 – millebi

4

あなたができることの1つは、enum implementsインターフェイスです。

インタフェース:

IMAGETYPEとして定義され
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として別の定義(ファイル・タイプの2種類の例を持っているだけに)ここではいくつかのサンプルコードを示します:

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()); 
    } 
} 

これは、私がちょうどいくつかのことを示す目的で一緒に叩いたやや粗いコードです。

主に、あなたがしようとしていることを解決する方法の1つと考えているので、各列挙型をインターフェイスにする方法を示したいと思っていました。あなたの列挙型をインターフェースに忠実にすることで、関数名が同じで、実装されていることを継承で保証することができます。

列挙型のコンストラクタのアイデア。この場合のコンストラクターでは、列挙名(DocType.POWERPOINTで示すように人間が判読可能な名前にすることができます)とその拡張子の間のマッピングを作成することができます。コードを見ている人なら誰でもPPT == powerpointを知っているだろうと確信していますが、もし必要ならば、その物の名前がもっとわかりやすいという事実を家に持ち帰りたいだけです。また必要に応じて、コンストラクタにパラメータを追加したり、複数のコンストラクタなどを持たせることもできます。

注意すべき重要なことは、あなたがこのように、列挙型自体の外部から列挙型の新しいタイプを作成しようとしないできことです:

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

私は、さらに詳細には触れません。これはすでに十分な長さですが、これを行うことはできません。列挙型のコンストラクタは、初期値(PDF、DOCなど)のリストでのみアクセス可能です。

最後にDavid Zが別の回答にコメントしているように、MyFileに工場設計パターンを実装することができますが、読者のための練習として残しておきます。

編集:

そして、あなたは、あなたが扱っているファイルタイプの種類を知っておく必要がある場合はもちろん、MyFilegetFileTypeのような機能を持たせることができる、またはそれはisDocTypeのような一連の機能を持つことができ、isImageTypeなどが含まれます。MyFileは完全なものではなく、あくまで例です。

関連する問題