2009-06-16 15 views
2

私はPHPからC#に移行しています。抽象的な新規/仮想/上書き/抽象キーワードの実際の例は何ですか?

PHPで継承クラスは、同じシグネチャを持つメソッドを持っていない限り、基本的に「基底クラスのメソッドは、それの世話をする、「カスケードオーバーライド」パターンを作成するために、抽象クラスを使用するのは簡単で分かりました" C#ので

が、しかし、私はちょうどキーワードの様々な組み合わせを試し、約20分を費やし新しいクラスを継承 仮想抽象、および ベースオーバーライドIまで最終的に、このシンプルなカスケードオーバーライドパターンを実行する適切な組み合わせを得ました。

したがって、以下のコードも私が望むように動作しますが、これらの追加されたキーワードは、C#が抽象クラスではるかに多くできることを私に示唆しています。私はこれらのキーワードの例を見て、基本的に彼らが何をしているのか理解していますが、この単純な「カスケードオーバーライド」パターン以外のものを使用する実際のシナリオは想像できません。 実際にとは何ですか?これらのキーワードを日々のプログラミングに実装する方法はありますか?動作

コード:

using System; 

namespace TestOverride23433 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] dataTypeIdCodes = { "line", "wn" }; 
      for (int index = 0; index < dataTypeIdCodes.Length; index++) 
      { 
       DataType dataType = DataType.Create(dataTypeIdCodes[index]); 
       Console.WriteLine(dataType.GetBuildItemBlock()); 
      } 

      Console.ReadLine(); 
     } 
    } 

    public abstract class DataType 
    { 
     public static DataType Create(string dataTypeIdCode) 
     { 
      switch (dataTypeIdCode) 
      { 
       case "line": 
        return new DataTypeLine(); 
       case "wn": 
        return new DataTypeWholeNumber(); 
       default: 
        return null; 
      } 
     } 

     //must be defined as virtual 
     public virtual string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the default datatype class"; 
     } 
    } 

    public class DataTypeLine : DataType 
    { 
     public DataTypeLine() 
     { 
      Console.WriteLine("DataTypeLine just created."); 
     } 
    } 

    public class DataTypeWholeNumber : DataType 
    { 
     public DataTypeWholeNumber() 
     { 
      Console.WriteLine("DataTypeWholeNumber just created."); 
     } 

     //new public override string GetBuildItemBlock() //base method is erroneously executed 
     //public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override" 
     public override string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the WHOLENUMBER class."; 
     } 
    } 

} 
+0

ここでは、メソッドの隠蔽を行うために「新規」を使用する(まれな)状況に関する注意事項をいくつか示します。 http://blogs.msdn.com/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx –

答えて

8

virtual/overrideコア多型対です。あなたはすでにこれらの

abstractvirtual似ていますが、なし賢明なベースの実装が存在しひび割れてきたように聞こえます。使用ケース:おそらくStreamです。実際の実装ではバイトを使って何かを行うには、が必要です()。これにより、クラスを強制的に強制的に避けるべきクラスがabstract

です。それはポリモーフィズムを破る...最も一般的なケースは、より具体的なシグネチャ/リターン型で再公開することです(おそらく密封クラスでは、チェーン上でもっときれいにならないので...) - SqlConnection.CreateCommand(vs DbConnection.CreateCommand)、または(おそらくより顕著)IEnumerator<T>.Current(あなたが既にそう、あなたの例からvirtualoverrideを考え出した表示されます

4

IEnumerator.Current VS:

  • 'abstract' はまたメンバーに適用することができ'virtual'の代わりに、メソッドの実装を指定していない場合( '; 'を署名の直後に挿入します)。これにより、すべての具体的な子孫がこのメソッドを実装するよう強制されます。

  • 'new'は、継承とは関係ありませんが、まったく同じシグネチャを持つ基本クラスのメンバを非表示にするためにメンバの子孫クラスで使用できます。一言で言えば

;)さらに他の回答に

1

子クラスが独自の処理を実行する、処理しない、または機能の親クラス処理を呼び出すことを許可する場合のオーバーライド。上書きクラスでは、オーバーライド関数または仮想関数を実装する必要はありません。

要約基本クラスで処理を実行したくなく、そのメソッドを継承クラスで実装したい場合。 (継承するクラスの振る舞いが大きく異なる場合に最適)。クラスに抽象メソッドだけが含まれている場合は、実質的にインターフェイス型です。抽象として指定された関数は、子クラスで実装されなくてはなりません(そうでなければ、コンパイラはエラーを投げます)。

関連する問題