6

検索しましたが、問題の解決策を見つけることができませんでした。私のシナリオは非常に単純です。

public class A
{
    public virtual void MethodOne()
    {
       Console.log( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "C" );
    }
}

私がやろうとしているのは、クラス C のインスタンス (「instanceC」と名付けます) に、その親のオーバーライドされたメソッドとその祖父母の両方を呼び出すことです。だから私はこれを期待します:

instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"

しかし、代わりにこれを取得しています:

instanceC.MethodOne();
// Output
// "A"
// "C"

クラス B のメソッドはスキップされます。これは不可能ですか?これが継承/ポリモーフィズムの要点だと思いました。前もって感謝します!

4

2 に答える 2

11

あなたの例は私にとって期待どおりに機能します。AB C を参照してください。あなたの最も可能性の高い問題は、C が B を拡張しないことだと思います。MethodOne のすべてのオーバーライドで、基本クラスからコードを実行する必要があるようです。すばらしい、継承はこれに適したパターンです。ただし、このパターンでは、継承者に基本ロジックを強制的に実行させることはできませんbase.MethodOne()。を呼び出したとしてもbase.MethodOne()、ロジックの順序を保証することはできません。彼らは電話しますかbase.MethodOne()メソッドの最初、メソッドの途中、またはメソッドの最後ですか? 多くの場合、これらのタイプのパターンでは、関数の先頭ですべての基本ロジックをサブクラスで実行する必要があります。次のパターンは、基本クラスが期待する順序で基本ロジックを実行するように継承者に強制します。技術的には柔軟性に欠けますが、基本クラスが指定する方法で継承者が基本クラスを拡張する必要があるため、より安全です。

public class A
{
    //Don't make this method virtual because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    public void MethodOne()
    {
        Console.WriteLine( "A" ); 
        MethodToBeOverriddenOne();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenOne() { }      
}

public class B : A
{
    //Seal the method because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    protected sealed override void MethodToBeOverriddenOne()
    {
        Console.WriteLine("B");
        MethodToBeOverriddenTwo();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenTwo() { }  
}

public class C : B
{
    protected sealed override void MethodToBeOverriddenTwo()
    {
        Console.WriteLine("C");
    }
}
于 2013-05-04T18:55:52.920 に答える
2

投稿した例は完全に機能します。実際のコードで行っていることは、投稿したものとは異なります。

これは、ideone で実行されているコードで、希望どおりに動作します。

using System;

public class Test
{
        public static void Main()
        {
                var c = new C();
                c.MethodOne();
        }
}

public class A
{
    public virtual void MethodOne()
    {
       Console.WriteLine( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "C" );
    }
}
于 2013-05-04T18:47:01.080 に答える