I have this code:
using System;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
Bar bar = new Bar();
Baz baz = new Baz();
Foo fooBar = new Bar();
Foo fooBaz = new Baz();
Bar barBaz = new Baz();
foo.Test();
bar.Test();
baz.Test();
fooBar.Test();
fooBaz.Test();
barBaz.Test();
Console.ReadLine();
}
}
internal class Foo
{
public virtual void Test()
{
Console.WriteLine("Foo");
}
}
internal class Bar : Foo
{
public new virtual void Test()
{
Console.WriteLine("Bar");
}
}
internal class Baz : Bar
{
public override void Test()
{
Console.WriteLine("Baz");
}
}
}
it outputs me:
Foo
Bar
Baz
Foo
Foo
Baz
But, I thought it should be:
Foo
Bar
Baz
Foo
Baz
Baz
Because Baz is overriding the method. What is happening here? Am I missing something? Why did the output for fooBaz.Test() is "Foo" instead of "Baz"?
Buz
is overriding the method, that's why
Bar barBaz = new Baz();
barBaz.Test();
will print Baz
.
But Bar
is not overriding - it is hiding the base method Test
and makes the new method virtual. Then Baz
is overriding the new method from Bar
, not the method from Foo
. So if you reference it like this: Foo fooBaz = new Baz();
then fooBaz
is treated like an instance of Foo
, which has no idea of the hiding method.
The output that you're expecting would be generated if you changed public new virtual void Test()
to public override void Test()
.
See also these topics:
When you use the new keyword on Bar.Test
you're saying it has no relation to Foo.Test
other than that it has the same name. Since Baz inherits from Bar, it overrides Bar.Test
but leaves Foo.Test
unmodified.
When you call fooBaz.Test
it looks up the unmodified Foo.Test
method and prints "Foo".
When you call barBaz.Test
it looks up the overriden Bar.Test
method and prints "Baz".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.