0

C# ポリモーフィズムでこのコード フォーム MSDN リソースを選びました。

public class A
{
    public virtual void DoWork() { }
}
public class B : A
{
    public override void DoWork() { }
}

public class C : B
{
    public override void DoWork()
    {
        // Call DoWork on B to get B's behavior:
        base.DoWork();

        // DoWork behavior specific to C goes here:
        // ...
    }
}

クラス C は B の DoWork() をオーバーライドしていますが、クラス B の DoWork() メソッドは仮想化されていません。C は B のすべてのメソッドとデータを継承するので、A の仮想メソッドも継承しますか (A は B の基本クラスであるため、B で使用できます)。

B が DoWork() の実装を提供しない場合、C は A の仮想メソッドのコピーに直接アクセスしてそれをオーバーライドするでしょうか?

また、C が B から継承する場合、A のメンバーの個別のコピーまたは B のメンバーのコピーを取得します。A のメンバーの個別のコピーについては、A を個別に継承する必要があると思います。

public class C : A, B

間違っている場合は修正してください。

編集 :

public class A 
{ 
    public virtual void DoWork() 
    { 
        Console.WriteLine("In Class A");  
    }
} 
public class B : A 
{ 
    public void DoWork() { Console.WriteLine("In Class B"); } 
} 
public class C : B 
{ 
    public void DoWork() 
    { 
        Console.WriteLine("In Class C"); 
        base.DoWork(); 
    } 
} 

これを VS C# で実行すると、virtual キーワードは必要ありません。クラス B の DoWork() ではキーワードをオーバーライドし、クラス B および C の DoWork() ではキーワードをオーバーライドします。つまり、パブリック クラス C のように、クラス名の定義でどの基本クラスが派生されているかを指定するだけでよいのでしょうか?

また、C# はクラスの多重継承のオプションを提供していないため、A のオブジェクトを明示的に作成し、それを使用して DoWork() にアクセスせずに、C のクラスから A の DoWork() の実装を直接使用する方法はありますか?

4

2 に答える 2

6

クラス C は B の DoWork() をオーバーライドしていると言われていますが、クラス B の DoWork() メソッドは仮想化されていません。

仮想メソッドをオーバーライドすると、明示的に .xml で封印しない限り、仮想メソッドは「そのまま」残りますsealed。(オーバーライド メソッドでもある場合にのみ、メソッドの修飾子を指定できます。)sealed

B が DoWork() の実装を提供しない場合、C は A の仮想メソッドのコピーに直接アクセスしてそれをオーバーライドするでしょうか?

はい。というか、実行時に A の実装を呼び出します。厳密には「コピー」ではありません。

また、C が B から継承する場合、A のメンバーの別のコピーを取得しますか?

ここであなたが何を意味するのかは本当に明確ではありません。どのような「コピー」のことで、どのメンバーですか? 各オブジェクトに含まれるフィールドを意味する場合、それは継承チェーンのすべてのクラスで宣言されたフィールドの和集合にすぎません。

編集:編集したコードでは、何もオーバーライドしていません。ポリモーフィックに呼び出されない新しいメソッドを宣言しています。したがって、次のように書くと:

A a = new C();
a.DoWork();

それは単に「In Class A」と出力しますが、仮想メソッドをオーバーライドBすると、「In Class C」と「In Class B」が出力されます。C

また、C# はクラスの多重継承のオプションを提供していないため、A のオブジェクトを明示的に作成し、それを使用して DoWork() にアクセスせずに、C のクラスから A の DoWork() の実装を直接使用する方法はありますか?

これがBoverridesの場合であると仮定するとDoWork、いいえ。それはカプセル化を破るでしょう - それはB例えば の不変条件を破る可能性があります。

于 2013-06-05T06:38:12.367 に答える
1

Cは から継承しています。Bこれは、 内のすべての仮想メソッドをオーバーライドできることを意味しますBOverrideメソッドはまだ仮想であることを意味します。の実装を提供しない
場合、inの実装は、通常の仮想動作と同様に、クラスの実装を呼び出します。基本呼び出しが正確にメソッドへの呼び出しであり、それ以外の呼び出しではないと想定しないでください。将来変更される可能性があるのは実装の詳細です。重要なことは、 の Nearet 親実装を呼び出すことです。BDoWorkbase.DoWorkCABDoWork

最後に、B を継承すると、すべてのプロパティ、メソッド、および から継承されたすべてのものも取得されAます。にはC#、多重継承のようなものはありません (つまりC : A, B、 where CAand Bare クラスは機能しません)。継承されたものを個別に取得することはできません。含まれているものをA取得するだけですB(もちろん、B継承されたものAなども含まれます)。

于 2013-06-05T06:43:19.860 に答える