2017-09-03 7 views
2

C#で継承の基礎を学びたいと思っており、スコープとアクセシビリティの理解にギャップがあることを認識しました。説明する例:オーバーライド時のスコープの違いと基底クラスメソッドの隠蔽との比較

using System.Windows.Forms; 

namespace InheritanceTests { 
    class Program { 
     public static void Main() { 
      (new A()).Foo();  // A: 1 
      (new B()).Foo();  // B: 2 
      ((A)(new B())).Foo(); // B: 2 (+) 
      (new C()).Foo();  // C: 3 
      ((A)(new C())).Foo(); // A: 1 (++) 
     } 
    } 
    class A { 
     private int x = 1; 
     public virtual void Foo() { MessageBox.Show("A: " + this.x); } 
    } 
    class B : A { 
     private int x = 2; 
     public override void Foo() { MessageBox.Show("B: " + this.x); } 
    } 
    class C : A { 
     private int x = 3; 
     public new void Foo() { MessageBox.Show("C: " + this.x); } 
    } 
} 

私はおそらく関連している(+)に関する質問と(++)を、持っている:

(+)に関しては、なぜBインスタンスのプライベートフィールドがした後もxアクセス可能ですAへのキャスト?

(++)に関して、AFooメソッドを実行すると、this.xは3と評価されないのですか?

答えて

0

(+)に関して、BインスタンスのプライベートフィールドxはなぜAへのキャストの後でもアクセスできますか?

誰にもアクセスできますか?あなたの例では、BA.Foo()(これはvirtual)をオーバーライドしているので、B.Foo()が呼び出されます。呼び出されるメソッドは実際にはクラスBであるため、このメソッドはBで宣言されたxフィールドを使用します。それは、その方法が見ることができる唯一のフィールドxです。

Aのフィールドxは、privateのため、Bには表示されません。それがあった場合でも、(それはprivate以外のものであれば、すなわち)、Bのフィールドxはそれを隠すだろうとFoo()B実装はまだありませんAから、Bクラスからxを使用します。

なぜ、AのFooメソッドを実行すると、this.xは3と評価されないのですか?この例では

、派生クラスCはないがAに元のメソッドをオーバーライドFoo()を有しています。代わりに、全く新しいメソッドFoo()と宣言されています。しかし、オブジェクトをAにキャストすることによって、コンパイラはCで宣言されたメソッドを知りません。表示できる唯一の方法はA.Foo()です。これはではなく、であり、Aの実装がFoo()と呼ばれています。

もちろん、その実装では、Aで宣言されたxフィールドのみが表示され、メソッド自体が宣言されています。したがって、3の代わりに1が出力されます。

関連する問題