16

C# を学習していますが、次の問題が発生しました。基本クラスと派生クラスの 2 つのクラスがあります。

class MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyBase::MyMethod()");
    }
}


class MyDerived: MyBase
{
    public void MyMethod()
    {
        Console.WriteLine("MyDerived::MyMethod()");
    }
}

とりあえずキーワード抜きvirtualで。これをコンパイルすると、クラスからoverride非表示にしようとしているという警告が表示されます (これは当然のことです) 。MyMethodMyBase

私がやりたいことは、派生クラスのインスタンスを持つ基本クラスからメソッドを呼び出すことです。私はこれを次のようにします:

MyDerived myDerived = new MyDerived();
((MyBase)myDerived).MyMethod();

virtualメソッドに , etc. キーワードを指定しないと問題なく動作します。キーワードの組み合わせを入れようとしたところ、次の結果が得られました。

| MyBase::MyMethod | MyDerived::MyMethod | Result printed on the console |
| -----------------|---------------------|-------------------------------|
| -                | -                   | MyBase::MyMethod()            |
| -                | new                 | MyBase::MyMethod()            |
| virtual          | new                 | MyBase::MyMethod()            |
| virtual          | override            | MyDerived::MyMethod()         |

表が明確であることを願っています。2 つの質問があります。

  1. 基底クラスから関数を呼び出すのは正しい方法ですか ( ((MyBase)myDerived).MyMethod();)? キーワードについては知ってbaseいますが、派生クラスの内部からしか呼び出すことができません。そうですか?
  2. 最後のケース (virtualおよびoverride修飾子を使用) で、呼び出されたメソッドが派生クラスから来たのはなぜですか? それについて説明していただけますか?
4

4 に答える 4

19

virtualメソッドをオーバーライドする型のインスタンスでメソッド を呼び出すと、基本クラスにキャストした場合でも、オーバーライドされたバージョンが常に呼び出されます。

メソッドをオーバーライドするクラスで仮想メソッドの基本実装を呼び出す唯一の方法は、baseキーワードを使用してメソッドを呼び出す派生クラス (基本クラスではない) で 2 番目のメソッドを作成することです。

一般に、これを行う必要があるのは、API 設計が不十分であることを示しています。基本バージョンを呼び出す必要があると思われる場合は、派生バージョンに別の名前を付ける必要があります。

于 2010-03-23T12:38:20.343 に答える
3

あなたは正しいです-base派生クラス内からのみ呼び出すことができます- Source

このページには、基本クラスの定義をオーバーライドする方法の例も示されています。

于 2010-03-23T12:40:44.980 に答える
3

2番目の質問については、参照しているオブジェクトのタイプを変更しているのではなく、参照しているインターフェイスだけを変更しています。したがって、A から継承し、関数 C をオーバーライドするオブジェクト B がある場合、B を A として参照しても、最も派生した型 (この場合は B) の実装を呼び出します。

于 2010-03-23T12:42:14.003 に答える
2
  1. そうですbase、特定のインスタンスの基本クラスを指します。
  2. 関連するメカニズムはポリモーフィズムと呼ばれます。警告なしで作業することをお勧めします。自然なオブジェクト指向の良い方法は、あなたが言及した最後のケースです。

ところで、置換の原則を強制するコードを書かないようにしてください。つまり、クラス階層の実装に依存するコードを書かないでください。新しい派生クラスをあなたの基本クラス。

于 2010-03-23T12:44:39.143 に答える