不要将方法隐藏与方法覆盖混为一谈。他们是两种完全不同的野兽。
隐藏方法时,仅在通过隐藏方法开头的类型访问方法时才隐藏它:
public class Foo
{
public string Blah() { return "Hi from Foo!"; }
}
public class DerivedFoo: Foo
{
public new string Blah() { return "Hi from DerivedFoo!"; }
}
现在我们有以下行为:
void TestFoos()
{
Foo foo = new Foo();
DerivedFoo derivedFoo = new DerivedFoo();
Foo derivedFooInDisguise = derivedFoo as Foo;
Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
Console.WriteLine(derivedFooInDisguise.Blah()); //Outputs "Hi from Foo!"
}
请注意,即使Blah
声明为,此行为也是相同的virtual
。有趣的部分是第三个调用。该方法通过Foo
类型化对象调用。由于它不是虚拟调用,Foo.Blah()
因此被调用,而不是DerivedFoo.Blah()
.
现在这与方法覆盖完全不同,其中虚拟方法调用始终解析为对象的运行时类型,而不是您调用它的类型:
public class Foo
{
public virtual string Blah() { return "Hi from Foo!"; }
}
public class DerivedFoo: Foo
{
public override string Blah() { return "Hi from DerivedFoo!"; }
}
现在我们有以下行为:
void TestFoos()
{
Foo foo = new Foo();
DerivedFoo derivedFoo = new DerivedFoo();
Foo derivedFooInDisguise = derivedFoo as Foo;
Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
Console.WriteLine(derivedFooInDisguise.Blah()); ////Outputs "Hi from DerivedFoo!"
}