new
修飾子によりメンバーが非表示になり、クラス階層のポリモーフィックな関係が失われます。のSayHi
メソッドは、'sとは異なる(オーバーライドではない)B
ものとして扱われます(したがって、キーワードとして「new」という単語を選択します)。次に、'sメソッドは'sではなく'sをオーバーライドします(これは非表示のままです)。A
C
B
A
したがって、参照を介しSayHi
てC
インスタンスを呼び出すA
と、ランタイムはA
タイプではなくC
タイプ(SayHi
から継承された「新しい」メソッドB
)に対してインスタンスを解決します。
一方、実行する場合:
B p = new C();
p.SayHi();
…期待される多形の結果が得られます。
From C
編集:ユースケースをリクエストしたので、これが1つです。.NET Framework 2.0でジェネリックスが導入される前は、より具体的な型を返すために、派生クラスの継承されたメソッドの戻り型(オーバーライド時に実行できないこと)を変更する手段としてメンバーの非表示が使用されることがありました。例えば:
class ObjectContainer
{
private object item;
public object Item
{
get { return item; }
set { item = value; }
}
}
class StringContainer : ObjectContainer
{
public new virtual string Item
{
get { return base.Item as string; }
set { base.Item = value as string; }
}
}
class QuotedStringContainer : StringContainer
{
public override string Item
{
get { return "\"" + base.Item + "\""; }
}
}
クラスのItem
プロパティはObjectContainer
プレーンを返しますobject
。ただし、ではStringContainer
、この継承されたプロパティは非表示になって、string
代わりにを返します。したがって:
ObjectContainer oc = new StringContainer();
object o = oc.Item; // Valid, since ObjectContainer.Item is resolved
string s1 = oc.Item; // Not valid, since ObjectContainer.Item is still resolved
string s2 = ((StringContainer)oc).Item;
// Valid, since StringContainer.Item is now resolved
クラスはのプロパティをQuotedStringContainer
オーバーライドし、その戻り型を継承します。ただし、それはまだの-returningプロパティから隠されています。この方法でなければ、異種の返品タイプを調整する方法はありません…</ p>
Item
StringContainer
string
object
Item
ObjectContainer
ObjectContainer oc = new QuotedStringContainer();
object o = oc.Item; // Valid, since ObjectContainer.Item is resolved
string s1 = oc.Item; // Not valid, since ObjectContainer.Item is still resolved
string s2 = ((StringContainer)oc).Item;
// Valid, since QuotedStringContainer.Item is now resolved
// (polymorphism!)
string s3 = ((QuotedStringContainer)oc).Item;
// Valid, since QuotedStringContainer.Item is now resolved