2012-03-23 8 views
0

私はファイルにテキストを書き込むプログラムを持っているとしましょう(実際はそうではありませんが、説明が簡単です)。私はFileTypeMasterを継承するPdfTypeやWordTypeのような、それぞれのファイルタイプごとに別々のクラスが必要です。クラスデザインC#キャスティング

今実際の問題に...私はユーザーがプログラムタイプをどのようなタイプで使用するかを決定します。 Pdf OR Wordが必要な場合、methodcallは同じに見えるはずです(単語は新しいもので、プログラムは以前はpdfのためだけでした)。それはPDFファイルでの例のために働く必要がありますどのように

それは言葉で動作するはずですどのように
static FileTypeMaster MyFavoriteType; //declare a general var 
MyFavoriteType = new PdfType(); //cast general var to the wanted type 
MyFavoriteType.CompileThis(); 

: 同じですが、MyFavoriteType =新しいWordType(); `

+1

は、これは少し混乱しています。最初のサンプルでは 'FileTypeMaster'は型の名前であるように見えますが、2番目のサンプルでは型が' MyFavoriteType'のように見えます。 – phoog

+0

私の答えにそのコメントが含まれています –

+0

申し訳ありません、私の間違いです。私は私の質問を編集しました。 (2番目のコードブロック) – CodingYourLife

答えて

4

インタフェースはそのために作られています。 MyFavoriteTypeは、あなたが必要とするもの(関数と財産)が組み込まれたインターフェースでなければなりません。 それぞれのタイプは、そのインターフェースを実装して独自のことを行います。

public interface Polygon 
{ 
    float GetArea(); 
} 
public class Square : Polygon 
{ 
    float Side; 
    public Square(float side) 
    { 
    Side = side; 
    } 
    Polygon.GetArea() 
    { 
    return side*side; 
    } 
} 

あなたは今ではのような何かを行うことができます:ここで

は小さな一例です

Polygon MyPolygon = new Square(5f); 
float area = MyPolygon.GetArea(); 

そして、これは正しくPolygonインタフェースを実装する任意の単一のクラスのために動作します。 はこれが可能である:あなたのケースでは

Polygon MyPolygon = new Circle(5f); 
float area = MyPolygon.GetArea(); 

は、インターフェースはそうのようになります。あなたはここで何をしたい

public interface MyFavoriteType//or name it FileTypeMaster, since that's what you want to anme it 
{ 
    void CompileThis(); 
} 
+0

IConvertable MyType = new PdfType(); (IConvertableはインターフェイスです)。それはまた動作していないようです...私は間違って何を考えている? – CodingYourLife

+0

申し訳ありませんがあなたのように動作します。名前空間は自動的に間違ってインタフェースに自動的に挿入されました。ありがとうございます – CodingYourLife

0

は、polymorphismを利用することです。実際に、あなたは親切オフは、WordやPDFのために、異なる実装をベースクラス(またはインタフェース)

public abstract class FileTypeMaster 
{ 
    public abstract CompileThis(); 
} 

を持っている必要があり、ここでstrategy design patternを実装している:で、

public class PdfType : FileTypeMaster 
{ 
    public override CompileThis() {} 
} 

次に、あなたの

FileTypeMaster x = new PdfType(); 
x.CompileThis() 

または

:プログラムを呼び出すには、正しい実装を作成できます。

は実際には、ファクトリクラスまたはファクトリメソッド使用して初期化を抽象化することができます他の記事に追加するには

public abstract class FileTypeMaster 
{ 
    public abstract CompileThis(); 

    public static FileTypeMaster Create(FileType type) 
    { 
     switch(type) 
     { 
      case FileType.Word : return new WordType(); 

      case FileType.Pdf : return new PdfType(); 

      default: 
       throw new NotImplementedException(); 
     } 
    } 
} 
+1

OOを使用している場合は、まずインターフェイスから始めてください。抽象クラスは、一般に、あるインタフェース実装コードを「標準」にするが、まだ変更可能である。 –

0

を、あなたは、一般的に、ANのようなインジケータ(与えられた工場を持っていますユーザーが選択したファイルタイプを表すenum値)は、適切なクラスのインスタンスを生成し、それをインターフェイスタイプとして返​​します。

+0

この場合、抽象と多態性を持つオブジェクト指向のアプローチが優れています。言語固有の動的プログラミングを使用できますが、実装するのが一般的に難しく、意味がわかっていればさらに閉鎖されます。 –

+0

@Shingetsu私はOO /多態的なアプローチを提唱しています。私はむしろ 'MyFavoriteType fileInstance = MyFavoiteTypeGenerator(userSelectedType);' 'MyFavoriteType fileInstance =新しいWordType();'よりも –

1

サブクラス間で振る舞いを共有する場合は、基本クラスのみを使用します。メソッドシグネチャとプロパティのみを共有する場合(たとえば、各サブクラスが基本クラスの機能を実際に使用していないなど)、代わりにインタフェースを使用します。

+0

はい、それは私が意味するものです。 OPのために、抽象クラスは通常、所有権とメソッドだけでなく、FIELDSも含めたいときにそこにあります。利点は、いくつかの "デフォルト"コードをあらかじめ書き込むことができることです。欠点は、あなたが1つだけを継承できることです。 –

0

ベースタイプは、クラスまたはインターフェイスのいずれかです。のは、それはインターフェースだとしましょう。そして、

interface IFileProcessor { void CompileThis(); } 
class PdfProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ } 
class WordProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ } 

private enum ProcessorType 
{ 
    Undefined, 
    Word, 
    Pdf 
} 

public void Main(string[] args) 
{ 
    ValidateArgs(args); // implementation omitted 
    ProcessorType requestedProcessor = GetRequestedProcessorFromArgs(args); // implementation omitted 
    IFileProcessor processor = GetProcessor(requestedProcessor); 
    processor.CompileThis(); 
} 

private IFileProcessor GetProcessor(ProcessorType requestedProcessorType) 
{ 
    switch (requestedProcessorType) 
    { 
     case ProcessorType.Pdf: 
      return new PdfProcessor(); 
     case ProcessorType.Word: 
      return new WordProcessor(); 
     default: 
      throw new ArgumentException("requestedProcessorType"); 
    } 
} 
関連する問題