16

新しい仮想キーワードを使用してメソッドを装飾する場合はどうなりますか?愛情は何ですか?インターフェイスを定義し、インターフェイスを継承するクラスを追加するのと同じです。ただし、新しい仮想を使用してインターフェイスメソッドを実現します。

 interface IPrinter
{
    void Print();
}

 public class PrinterOne : IPrinter
{
    public void Print() 
    {
        Console.WriteLine("PrinterOne.");
    }
}

public class PrinterTwo : PrinterOne
{
    public new virtual void Print()
    {
        Console.WriteLine("PrinterTwo.");
    }
}

public class PrinterThree : PrinterTwo
{
    public override void Print()
    {
        Console.WriteLine("PrinterThree.");
    }
}

public class PrinterFour : PrinterThree
{
    public override void Print()
    {
        Console.WriteLine("PrinterFour.");
    }
}

 static void Main(string[] args)
    {
        IPrinter iprinter = new PrinterFour();
        iprinter.Print();//the output is PrinterOne? why???
        Console.ReadLine();
    }
4

4 に答える 4

16

newvirtualは2つの(ほとんど-)無関係なキーワードです。

new基本メソッドをシャドウすることを意味します。
virtualサブクラスがそれをオーバーライドできるようにします。

インターフェイスを介してメソッドを呼び出すと、基本メソッドが呼び出されます。これは、基本メソッドが呼び出されずvirtual、派生クラスがインターフェイスを明示的に再実装しないためです(これにより、メソッドが再マップされます)。

于 2012-05-02T14:36:11.430 に答える
11

このnewように使用されるキーワードは、メンバーの非表示です。

virtualキーワードと組み合わせて使用​​されるのを見たことがありません。これは、メソッドの実装PrinterTwoから派生する型を許可するだけです。overridePrint

このnewように使用されるキーワードを使用すると、型自体の変数を使用している場合に限り、型で基本型のメンバーを非表示にできます。

たとえば、次のことを行う場合:

PrinterOne one = new PrinterTwo();
one.Print();

継承チェーンの一部ではないため、メソッドは呼び出されません。PrinterTwo

いつこれを行うかについては...本当に、私が考えることができず(おそらく反射?)、でコードを編集できないという奇妙な理由で本当に必要な場合PrinterOne

個人的に、私はこれを決してしません。

出力がプリンター1である理由については、IPrinter.Print呼び出しは、それが定義されているタイプ(PrinterOneこの場合)に対して呼び出されます。これにより、newキーワードを特徴とするタイプと話さない限り、キーワードが無視されるという上記の例に戻ります。 。

基本的に、使用は上記の私の小さな例で使用するのIPrinterと似ています。PrinterOne

この問題を解決するには、PrinterOneメソッドを作成し、 invirtualの使用を完全に削除します。new virtualPrinterTwo

于 2012-05-02T14:36:02.677 に答える
5

新しい修飾子

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

newキーワードを修飾子として使用すると、基本クラスから継承されたメンバーが明示的に非表示になります。

これは、メソッドが仮想基本クラスのメソッドをオーバーライドしないことを意味しますが、派生クラスのインスタンスで呼び出された場合でも優先されます。つまり、新しいメソッドは、基本クラスではなく、派生クラスの変数にのみ影響します。

仮想修飾子

http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx

virtualキーワードは、メソッド、プロパティ、インデクサー、またはイベント宣言を変更し、派生クラスでオーバーライドできるようにするために使用されます。

これは、派生クラスでメソッドをオーバーライドできることを意味します。仮想メソッドをオーバーライドした派生クラスのインスタンスを保持する基本クラス変数で仮想メソッドを呼び出すと、派生クラスの実装が呼び出されます。これは、新しいキーワードの動作の反対です。

于 2012-05-02T14:42:43.803 に答える
2

これはメソッド非表示と呼ばれます。これは、オーバーライドできないメソッドに独自の実装を提供する必要がある場合に使用します。PrinterOne.Printは仮想メソッドではないため、オーバーライドできません。代わりに、newキーワードを使用して、元のメソッドを非表示にする同一のメソッドシグネチャを作成します。代わりに新しい方法が使用されます。これにキーワードを追加するvirtualと、クラスを派生させることで新しいメソッドをオーバーライドできます。

元のメソッドを非表示にする新しいメソッドは、定義コンテナ(例)を介して呼び出す場合にのみ呼び出されますPrintTwo。インターフェイスで呼び出すと、元のメソッドが呼び出されます。メソッドが削除または置換されたことがないため、インターフェイスに直接アクセスすることで元の実装が引き続き存在することに注意してください。

于 2012-05-02T14:38:29.270 に答える