5

クラスをベースクラスにキャストするときに、オーバーライドされたメソッドが呼び出される理由を誰かが説明してくれますか?

    class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    sealed class Derived : Base
    {
        public override void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }

    static void Main(String[] args)
    {
        Derived d = new Derived();
        ((Base)d).VirtualMethod();
    }

つまり、このコードは次のように出力されます。

Overriden method

ではない

Base virtual method

実行時またはコンパイル時の未来ですか?

ベースの仮想メソッドを呼び出して派生したものから呼び出すことができることは知ってbase.VirtualMethod()いますが、外部から呼び出すことはできますか? (fromMainまたは他のクラスのように)

4

2 に答える 2

9

メソッドの実装は、オブジェクトの実行時の型に基づいて選択されます。それがポイントの大部分です。誰でも使用できます:

public void Foo(Base b)
{
    b.VirtualMethod();
}

...そして、ポリモーフィズムがそれを処理するため、実行タイプが何であるかを知ったり気にしたりする必要はありません。

base.VirtualMethod() を呼び出して派生からベースの仮想メソッドを呼び出すことができることは知っていますが、外部から呼び出すことはできますか?

いいえ(少なくとも、仮想メソッドを非仮想的に呼び出すための恐ろしいハッカーがないわけではありません)、それはカプセル化の意図的な部分です。オーバーライドする実装は、そのオブジェクトの元の実装を効果的に置き換えました。

于 2013-02-28T16:43:57.280 に答える
2

基本実装にアクセスしたい場合は、override を使用しないでください。new を使用する必要があります。Override は任意の親実装をオーバーライドし、new は親実装を「非表示」にするため、親オブジェクトとしてキャストしてからメソッドを呼び出すことで実装にアクセスできます。

internal class Program
{
    private static void Main(string[] args)
    {
        Derived d = new Derived();
        d.VirtualMethod();
        ((Base) d).VirtualMethod();

        Console.ReadLine();
    }

    private class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    private sealed class Derived : Base
    {
        public new void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }
}

これは出力されます:

オーバーライドされたメソッド
ベースの仮想メソッド

于 2013-02-28T17:03:36.413 に答える