-1

以下のコードで。

class Program
{
    static void Main(string[] args)
    {
        BaseClass obj = new BaseClass();
        DerivedClass obj2 = new DerivedClass();

        var x = obj.Method(2);
        var z = obj2.Method(1);
    }
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public string Method(int i) { return i.ToString(); }
}

派生クラスにメソッドがある場合、派生クラス オブジェクトが独自の関数を呼び出し、それがない場合、派生クラス オブジェクトが基本関数を呼び出しているのはなぜですか?

4

4 に答える 4

1

この動作をオーバーライドしたい場合は、派生元のクラスのメンバーを明示的に非表示にするnew 修飾子でメソッドをマークできます。

public new string Method(int i) { return i.ToString(); }
于 2013-03-11T08:30:22.267 に答える
0

継承とは、DerivedClass持っているすべてのメンバーを自動的に持つことを意味しますBaseClass。したがって、Methodを返すもありますint

で、同じ名前と同じ引数を持つ新しいメソッドを導入するのは悪い考えDerivedClassです。thenDerivedClassには同じシグネチャを持つ 2 つのメソッドがあるためです。そのため、コンパイラから警告が表示されます。キーワードの修飾子を使用すると警告が消えたとしてもnew、同じシグネチャを持つ 2 つのメソッドを使用することはお勧めできません。

代わりに、メソッドの未使用の名前を選択DerivedClassしてください。

あなたの質問にもっと直接的に答えるには:Method中に書いたメソッドが 1 つしかない場合はBaseClass、すべて問題ありません。はこのメソッドDerivedClass を継承します。これが、 で呼び出すことができる理由ですobj2。しかし、 で 2 番目のメソッドを導入する場合DerivedClass、呼び出しobj2.Method(1);では 2 つのメソッドから選択する必要があります。残念ながら、同じシグネチャを持つメソッドが 2 つあるからです。この場合のルールは、 で定義されたメソッドを選択することDerivedClassです。ただし、ここで重要なのはコンパイル時の型であることに注意してください。だから言ったら

BaseClass obj3 = new DerivedClass();
var w = obj3.Method(42);

の実行時の型が であってobj3DerivedClass、コンパイル時の型のために最初に呼び出されるメソッドです。私が言ったように、obj3両方の方法を持っています。

于 2013-03-11T08:35:19.577 に答える
0

これについて、コンパイラから警告を受け取っているはずです。新しいMethod()メソッドは暗黙的にベースを隠しています (キーワードを使用してこれを明示的にすることができます。これnewにより、コンパイラの警告もサイレンスされます)。http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspxも参照してください。

C# では、出力型のみに基づいてメソッドをオーバーロードすることはできないことに注意してください。新しいメソッドがたまたま a を返すstringからといって、その署名がベースの署名と異なるわけではありません。

隠れることの危険性に関する次の警告に注意してください。これは、何が起こっているのかを説明するのにも役立ちます。

static void Main(string[] args)
{
    BaseClass obj = new BaseClass();
    DerivedClass obj2 = new DerivedClass();

    var x = obj.Method(2); //returns 2
    var z = obj2.Method(1); //returns 2 (2*2)
    var a = ((BaseClass)obj2).Method(1); //returns 1 (base's implementation!)
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public int Method(int i) { return i * 2; }
}

これは、新しいオーバーロードを追加する次のコードの動作とは異なります。Method(string)

static void Main(string[] args)
{
    BaseClass obj = new BaseClass();
    DerivedClass obj2 = new DerivedClass();

    var x = obj.Method(2); //returns 2
    var z = obj2.Method("1"); //returns "1"
    var a = ((BaseClass)obj2).Method("1"); //returns "1"
}

class BaseClass
{
    public int Method(int i) { return i; }
}

class DerivedClass : BaseClass
{
    public string Method(string s) { return s; }
}
于 2013-03-11T08:31:42.657 に答える
0

これは、派生クラスで基本メソッドを非表示にし、派生クラスのオブジェクトを作成すると、独自の実装が呼び出されるためです。適切なメカニズムなしで( new キーワードを使用して)実行すると、コンパイラーは叫び、派生クラスにメソッドがない場合、基本クラスの実装が開始されます。

于 2013-03-11T08:35:25.027 に答える