MSDN では、次のように言及されています。
http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.80).aspx
この項目が「オーバーライド修飾子を使用するプロパティ宣言を含めることにより、派生クラスで仮想継承プロパティをオーバーライドできる」とはどういう意味ですか?
(これは、仮想と抽象の2番目の違いです)
前もって感謝します、ジョージ
MSDN では、次のように言及されています。
http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.80).aspx
この項目が「オーバーライド修飾子を使用するプロパティ宣言を含めることにより、派生クラスで仮想継承プロパティをオーバーライドできる」とはどういう意味ですか?
(これは、仮想と抽象の2番目の違いです)
前もって感謝します、ジョージ
仮想と抽象の唯一の違いは、抽象メソッドまたはプロパティは、それが定義されているクラス (抽象クラス) に実装されておらず、サブクラスでオーバーライドする必要があることです。一方、仮想メソッドまたはプロパティは、それが定義されているクラスに実装されているため、サブクラスでオーバーライドすることは必須ではありません。
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;
}
}
混乱は理解できます。私は以前にそこにいたので、基本的な違いをまっすぐに保つ方法を共有します...
virtual
対abstract
:
クラスのメソッド (またはプロパティ) が マークされvirtual
ている場合、そのクラスから継承
(別名* 派生override
) する
ことを選択した場合
、キーワードを使用してオーバーライドできます。このキーワードは、メソッドが呼び出される実際のメソッドである場合とそうでない場合があるという考えを喚起することを目的としています。したがって、私は常にメンバーをデフォルトの実装と考えています。つまり、クラスのメソッドなど、手で食べることを伴う可能性のある一般化できる機能を表すことを意味します。ただし、クラスはデフォルトの実装をオーバーライドする可能性がありますvirtual
virtual
Eat()
Human
ChineseHuman
Eat()
、代わりにチョップスティックを使用する実装を可能にするため。最後に、仮想メソッドとプロパティは既定の実装であるため、そのメンバーを定義するクラスは、メソッドまたはプロパティの完全な実装を提供する必要があります。すべてのHuman
オブジェクトは、方法を知っている Eat()
必要があります。
オブジェクト指向の考え方は、virtual
メンバーが本能を表すと宣言するかもしれません。ToEat()
は、クラス オブジェクトの本能です。Human
AChineseHuman
は箸で学ぶことができEat()
ます。
クラス メソッド (またはプロパティ) がマークされている場合、そのクラスから継承する
ことを選択した場合は、キーワードを使用してオーバーライドabstract
する必要があります
。このキーワードは、クラスがメンバーによって表される機能のみをサポートし、その機能に対して一般化できる共通のロジックがないという考えを喚起することを目的としています。つまり、メンバーは概念的なものにすぎないため、実装がありません。継承関係を実装するときに C# がメンバーを抽象化するように要求するのは少し紛らわしいですが、この場合、具体的な実装で空の概念をオーバーライドしていることを意味します。の例override
abstract
abstract
override
abstract
Human
クラスのメンバーはSpeak()
. Human
表現には言語が必要なため、すべてのオブジェクトに共通の話し方はなく、本能的でもありません。Speak()
注: 代わりにに属していると主張する人もいるかもしれませんinterface
。
オブジェクト指向の考え方では、abstract
メンバーは習得すべき行動 (方法)と習得すべき知識または信念 (特性)を表すと宣言する場合があります。ToSpeak()
は、クラス オブジェクトの学習された動作です。Human
Aは、 とは異なる方法でChineseHuman
学習する可能性があり、どちらも両方であるという理由だけで方法を知りません。Speak()
EnglishHuman
Speak()
Human
ニュアンス:
virtual
メソッドをオーバーライドする必要はありません。virtual
クラスのようなものはありません。abstract
abstract
メンバーはクラスにのみ表示できます。上記の例ではabstract
、クラスにメソッドがあるということは、それがクラスであるHuman
ことを意味するため、フレーズ を使用して aをインスタンス化することはできません。代わりに、クラスは から継承し、 としてインスタンス化する必要があります。aは aであり、両方とも から継承するため、ではなくから継承できます。存在するということは、私たち全員が単なるもの以上のものだからです。Human
abstract
Human
var baby = new Human();
BabyHuman
Human
var baby = new BabyHuman();
BabyHuman()
Human
EnglishHuman
ChineseHuman
Human
EnglishHuman
BabyHuman
Human
Human
abstract
Human
abstract
メンバーを非表示にすることはできません。override
実装のみを非表示にすることができます (継承チェーンのさらに上)。たとえば、メソッドを としてBabyHuman
実装する必要があります。がから継承する場合、キーワードを使用して独自の実装で の実装を非表示にすることができます (以下の「C# でのメソッドの非表示」リファレンスを参照)。abstract
Speak()
override
EnglishHuman
BabyHuman
BabyHuman
Speak()
new
abstract
クラスはvirtual
メンバーを持つことができます。interface
これがクラスとクラスの主な違いabstract
です。その意味で、abstract
クラスはコントラクトとクラスの動作のテンプレートの両方を定義できますが、 はコントラクトinterface
のみを定義します。コード参照:
それについて何が混乱しているのか説明できますか?プロパティは、他のメソッドと同様にオーバーライドできます。
public class Base {
public virtual int Prop1 { get { ... } set { ... } }
}
public class Derived : Base {
public override int Prop1 { get { ... } set { ... } }
基本クラスでメソッド virtual を宣言すると、派生クラスでそれをオーバーライドできます。
例
class MyBaseClass
{
public virtual void MyOverridableMethod()
{
...
}
}
class MyDerivedClass : MyBaseClass
{
public override void MyOverridableMethod()
{
...
}
}
MyDerivedClass のオーバーライド修飾子に注目してください。
さて、基本クラスがあり、その基本クラス自体が別のクラスから派生しているとしましょう。
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 のように) 実装を持つことができるため、クラス抽象をマークする必要はなく、それらをインスタンス化できます。