1

MSDN では、次のように言及されています。

http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.80).aspx

この項目が「オーバーライド修飾子を使用するプロパティ宣言を含めることにより、派生クラスで仮想継承プロパティをオーバーライドできる」とはどういう意味ですか?

(これは、仮想と抽象の2番目の違いです)

前もって感謝します、ジョージ

4

5 に答える 5

10

仮想と抽象の唯一の違いは、抽象メソッドまたはプロパティは、それが定義されているクラス (抽象クラス) に実装されておらず、サブクラスでオーバーライドする必要があることです。一方、仮想メソッドまたはプロパティは、それが定義されているクラスに実装されているため、サブクラスでオーバーライドすることは必須ではありません。

public abstract AbstractClass
{
    // This class cannot be instantiated, since it is 
    // abstract, and the class is abstract because
    // it has an abstract member

    public abstract MyProperty {get; set; }
}

AbstractClass から派生するクラス (上記の AbstractClass は説明目的のためのものです。実装を持つメソッド/プロパティがないため、抽象クラスの代わりにインターフェイスを作成できます) の実装を提供する必要があります。MyProperty. そうしないと、コンパイルされません。MyProperty を「オーバーライド」することでこれを行います。新しいメンバーを導入するのではなく、以前に定義されたプロパティの実装を提供するだけです。

public class ConcreteClass : AbstractClass
{
    public override MyProperty {
       get
       {
            return _someValue;
       }
       set
       {
            if( _someValue != value ) _someValue = value;
       }
}
于 2009-03-03T13:13:14.363 に答える
6

混乱は理解できます。私は以前にそこにいたので、基本的な違いをまっすぐに保つ方法を共有します...

virtualabstract:

  • クラスのメソッド (またはプロパティ) が マークされvirtualている場合、そのクラスから継承 (別名* 派生override) する ことを選択した場合 、キーワードを使用してオーバーライドできます。このキーワードは、メソッドが呼び出される実際のメソッドである場合とそうでない場合があるという考えを喚起することを目的としています。したがって、私は常にメンバーをデフォルトの実装と考えています。つまり、クラスのメソッドなど、手で食べることを伴う可能性のある一般化できる機能を表すことを意味します。ただし、クラスはデフォルトの実装をオーバーライドする可能性があります

    virtualvirtualEat()HumanChineseHumanEat()、代わりにチョップスティックを使用する実装を可能にするため。最後に、仮想メソッドとプロパティは既定の実装であるため、そのメンバーを定義するクラスは、メソッドまたはプロパティの完全な実装を提供する必要があります。すべてのHumanオブジェクトは、方法を知っている Eat()必要があります。

    オブジェクト指向の考え方は、virtualメンバーが本能を表すと宣言するかもしれません。ToEat()は、クラス オブジェクトの本能です。HumanAChineseHumanは箸で学ぶことができEat()ます。

  • クラス メソッド (またはプロパティ) がマークされている場合、そのクラスから継承する ことを選択した場合は、キーワードを使用してオーバーライドabstractする必要があります 。このキーワードは、クラスがメンバーによって表される機能のみをサポートし、その機能に対して一般化できる共通のロジックがないという考えを喚起することを目的としています。つまり、メンバーは概念的なものにすぎないため、実装がありません。継承関係を実装するときに C# がメンバーを抽象化するように要求するのは少し紛らわしいですが、この場合、具体的な実装で空の概念をオーバーライドしていることを意味します。の例override

    abstractabstractoverrideabstractHumanクラスのメンバーはSpeak(). Human表現には言語が必要なため、すべてのオブジェクトに共通の話し方はなく、本能的でもありません。Speak()注: 代わりにに属していると主張する人もいるかもしれませんinterface

    オブジェクト指向の考え方では、abstractメンバーは習得すべき行動 (方法)と習得すべき知識または信念 (特性)を表すと宣言する場合があります。ToSpeak()は、クラス オブジェクトの学習された動作です。HumanAは、 とは異なる方法でChineseHuman学習する可能性があり、どちらも両方であるという理由だけで方法を知りません。Speak()EnglishHumanSpeak()Human

ニュアンス:

  • virtualメソッドをオーバーライドする必要はありません。
  • virtualクラスのようなものはありません。
  • abstractabstractメンバーはクラスにのみ表示できます。上記の例ではabstract、クラスにメソッドがあるということは、それがクラスであるHumanことを意味するため、フレーズ を使用して aをインスタンス化することはできません。代わりに、クラスは から継承し、 としてインスタンス化する必要があります。aは aであり、両方とも から継承するため、ではなくから継承できます。存在するということは、私たち全員が単なるもの以上のものだからです。HumanabstractHumanvar baby = new Human();BabyHumanHumanvar baby = new BabyHuman();BabyHuman()HumanEnglishHumanChineseHumanHumanEnglishHumanBabyHumanHumanHumanabstractHuman
  • abstractメンバーを非表示にすることはできません。override実装のみを非表示にすることができます (継承チェーンのさらに上)。たとえば、メソッドを としてBabyHuman実装する必要があります。がから継承する場合、キーワードを使用して独自の実装で の実装を非表示にすることができます (以下の「C# でのメソッドの非表示」リファレンスを参照)。abstract Speak()overrideEnglishHumanBabyHumanBabyHumanSpeak()new
  • abstractクラスはvirtualメンバーを持つことができます。interfaceこれがクラスとクラスの主な違いabstractです。その意味で、abstractクラスはコントラクトとクラスの動作のテンプレートの両方を定義できますが、 はコントラクトinterfaceのみを定義します。

コード参照:

于 2009-04-16T17:07:55.710 に答える
1

それについて何が混乱しているのか説明できますか?プロパティは、他のメソッドと同様にオーバーライドできます。

public class Base {
  public virtual int Prop1 { get { ... } set { ... } }
}

public class Derived : Base {
  public override int Prop1 { get { ... } set { ... } }
于 2009-03-03T13:12:29.280 に答える
1

基本クラスでメソッド virtual を宣言すると、派生クラスでそれをオーバーライドできます。

class MyBaseClass
{
   public virtual void MyOverridableMethod()
   {
          ...
   }

}

class MyDerivedClass : MyBaseClass
{
   public override void MyOverridableMethod()
   {
         ...
   }
}

MyDerivedClass のオーバーライド修飾子に注目してください。

于 2009-03-03T13:13:08.000 に答える
1

さて、基本クラスがあり、その基本クラス自体が別のクラスから派生しているとしましょう。

public class Bar : Foo
{
   virtual public int SomeProperty { get; set; }
}

virtual キーワードが意味することは、Bar から派生したクラスでは、SomeProperty をオーバーライドしてその動作を変更できるということです。

public class Baz : Bar
{
   private int thisInt;
   override public int SomeProperty 
   {
      get { return thisInt; }
      set 
      {
         if(value < 0)
         {
            throw new ArgumentException("Value must be greater than or equal to zero.");
         }
         thisInt = 0;
      }
   }
}

明確化:タイプ Baz のオブジェクトが使用されると、タイプが Bar にキャストされない限り、そのバージョンの SomeProperty が呼び出されます。Baz の SomeProperty を仮想として定義すると、Baz から派生したクラスもそれをオーバーライドできます (実際、それが必要な場合があります。頭の中で思い出すことはできません)。

さらなる明確化:抽象メソッドには実装がありません。クラスにクラスを追加するときは、クラスを抽象としてマークする必要があり、次のように新しいインスタンスをインスタンス化することはできません。

MyAbstractType m = new MyAbstractType();

一方、仮想メンバーは (上記の SomeProperty のように) 実装を持つことができるため、クラス抽象をマークする必要はなく、それらをインスタンス化できます。

于 2009-03-03T13:14:57.213 に答える