I'm having the following classes:
class Base
{
public virtual void Print()
{
Console.WriteLine("Base");
}
}
class Der1 : Base
{
public new virtual void Print()
{
Console.WriteLine("Der1");
}
}
class Der2 : Der1
{
public override void Print()
{
Console.WriteLine("Der2");
}
}
This is my main method:
Base b = new Der2();
Der1 d1 = new Der2();
Der2 d2 = new Der2();
b.Print();
d1.Print();
d2.Print();
The output is Base
, Der2
, Der2
.
As far as I know, Override won't let previous method to run, even if the pointer is pointing to them. So the first line should output Der2
as well. However Base
came out.
How is it possible? How the override didn't work there?
override
will replace the previous method, but as yourDer1
class doesn't overridePrint()
(it Shadows it, to use a VB-ism), then the most overriden verion ofBase
'sPrint()
is called, which happens to be the version it definesIt's because
Der1
does not overridePrint
, it replaces it with a brand new method that happens to have the same name (this is caused by the use of thenew
keyword). So, when the object is cast toBase
it callsPrint
inBase
; there is no override to call..As everyone has said the class
Der1
is replacingPrint()
instead of overriding it. To see this in action you could based1
andd2
toBase
and then call the print method. It will then returnBase
.You've never actually overriden the
Base
version ofPrint()
. You've only hidden it with a separate virtual method (named the same) inDer1
.When you use the
new
keyword on a method signature - you are telling the compiler that this is a method that happens to have the same name as a method of one of your base classes - but has no other relation. You can make this new method virtual (as you've done) but that's not the same as overriding the base class method.In
Der2
when you overridePrint
you are actually overriding the 'new' version that you declared inDer1
- not the version isBase
. Eric Lippert has an excellent answer to a slightly different question that may help you reason about how virtual methods are treated in the C# language.In your example, when you call
Print
, you are calling it in the first case through a reference of typeBase
- so the hidden (but not overriden) version ofPrint
is called. The other two calls are dispatched toDer1
's implementation, because in this case, you've actually overriden the method.You can read more about this in the MSDN documentation of new and override.
What you may have intended to do with Der1 (as you did with Der2) is to use the
override
keyword: