当覆盖vs隐藏基类方法时C#范围差异
问题描述:
我想了解C#中继承的基础知识,并意识到我对范围和可访问性的理解存在差距。一个例子来说明:当覆盖vs隐藏基类方法时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
?
关于(++),为什么当A
的Foo
方法执行时this.x
没有评估为3?
答
关于(+),为什么B实例的私有字段x即使在转换为A后也可以访问?
接触谁?在你的例子中,B.Foo()
被调用,因为B
已被覆盖A.Foo()
(这是virtual
)。由于所调用的方法实际上在类别B
中,所以该方法使用在B
中声明的x
字段。这是该方法可以看到的唯一字段x
。
该字段x
在A
对B
无效,因为它是private
。但是,如果它是(即如果它比其他private
东西),在B
领域x
将其隐藏和B
实施Foo()
将仍然使用x
从B
类,而不是从A
。
关于(++),为什么当A的Foo方法执行时,this.x不会评估为3?
在这个例子中,派生类C
具有不在A
重写原来的方法Foo()
。相反,它被宣布为一个全新的方法Foo()
。但是通过将对象转换回A
,编译器不再知道在C
中声明的方法。它可以看到的唯一方法是A.Foo()
,这是而不是重写,因此调用Foo()
的A
执行。
当然,该实现只能看到在A
中声明的x
字段,其中声明了方法本身。因此,您在输出中获得1
而不是3
。