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?
You've never actually overriden the Base version of Print(). You've only hidden it with a separate virtual method (named the same) in Der1.
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 override Print you are actually overriding the 'new' version that you declared in Der1 - not the version is Base. 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 type Base - so the hidden (but not overriden) version of Print is called. The other two calls are dispatched to Der1'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:
class Base
{
public virtual void Print()
{
Console.WriteLine("Base");
}
}
class Der1 : Base
{
// omitting 'new' and using override here will override Base
public override void Print()
{
Console.WriteLine("Der1");
}
}
It's because Der1 does not override Print, it replaces it with a brand new method that happens to have the same name (this is caused by the use of the new keyword). So, when the object is cast to Base it calls Print in Base; there is no override to call..
override will replace the previous method, but as your Der1 class doesn't override Print() (it Shadows it, to use a VB-ism), then the most overriden verion of Base's Print() is called, which happens to be the version it defines
As everyone has said the class Der1 is replacing Print() instead of overriding it. To see this in action you could base d1 and d2 to Base and then call the print method. It will then return Base.
((Base)d2).Print(); //Base
Related
This question already has answers here:
Difference between shadowing and overriding in C#?
(6 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.
when use new virtual key words to decorate the method? what is the affection? Like define an interface, and add a class to inherit the interface. but use the new virtual to realize the interface method.
interface IPrinter
{
void Print();
}
public class PrinterOne : IPrinter
{
public void Print()
{
Console.WriteLine("PrinterOne.");
}
}
public class PrinterTwo : PrinterOne
{
public new virtual void Print()
{
Console.WriteLine("PrinterTwo.");
}
}
public class PrinterThree : PrinterTwo
{
public override void Print()
{
Console.WriteLine("PrinterThree.");
}
}
public class PrinterFour : PrinterThree
{
public override void Print()
{
Console.WriteLine("PrinterFour.");
}
}
static void Main(string[] args)
{
IPrinter iprinter = new PrinterFour();
iprinter.Print();//the output is PrinterOne? why???
Console.ReadLine();
}
new and virtual are two (mostly-) unrelated keywords.
new means it shadows the base method.
virtual allows subclasses to override it.
Calling the method through the interface results in the base method being called, since the base method is not virtual and the derived classes don't explicitly re-implement the interface (which would cause the method to be re-mapped)
The new keyword used like this is member hiding.
I have never seen it used in conjunction with the virtual keyword, mind you. It is simply allowing types that derive from PrinterTwo to override the Print method implementation.
The new keyword used this way allows a type to hide the members of base types, but only if you are using a variable of the type itself.
For example, if you were to do:
PrinterOne one = new PrinterTwo();
one.Print();
It would not call the method in PrinterTwo as it is not part of the inheritance chain.
As for when you would do this... when you really, really need to for some odd reason that I can't think of (reflection maybe?) and you cannot edit the code in PrinterOne.
Personally, I wouldn't ever do this.
As for why the output is printer one... calling IPrinter.Print will call against the type it is defined on (PrinterOne in this case), which will put you back in my above example about the new keyword being ignored unless you talk to the type that features it.
Basically, using IPrinter is analogous to using PrinterOne in my small example above.
To solve the problem, make the PrinterOne method virtual and completely remove the use of new virtual in PrinterTwo.
new modifier
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
When used as a modifier, the new keyword explicitly hides a member inherited from a base class.
This means that the method does not override the virtual base class method, but it still takes precedence when called on an instance of the derived class. In other words, the new method only affects a variable of the derived class, not the base class.
virtual modifier
http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx
The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class.
This means that the method can be overriden in a derived class. When you call a virtual method on a base class variable which holds an instance of the derived class that has overridden the virtual method, the derived class implementation is called. This is the opposite of the behaviour of the new keyword.
This is called method hiding. You use this when you need to provide your own implementation for a method that cannot be overridden. Because PrinterOne.Print is not a virtual method, it cannot be overridden. Instead, the new keyword is used to create a identical method signature that hides the original method. The new method will be used instead. Adding the virtual keyword to this, allows your new method to be overridden by deriving classes.
Your new method that hides the original will only be invoked if you call it through the defining container (eg. PrintTwo). Calling it by the interface calls the original method. Mind you, that the method was never removed or replaced so the original implementation still exists by accessing the interface directly.
Today I came up with an interesting problem. I noticed that the following code:
class A
{
public A()
{
Print();
}
public virtual void Print()
{
Console.WriteLine("Print in A");
}
}
class B : A
{
public B()
{
Print();
}
public override void Print()
{
Console.WriteLine("Print in B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
}
}
Prints
Print in B
Print in B
I want to know why does it print the "Print in B" twice.
I want to know why does it print the "Print in B" twice.
You're calling a virtual method twice, on the same object. The object is an instance of B even during A's constructor, and so the overridden method will be called. (I believe that in C++, the object only "becomes" an instance of the subclass after the base class constructor has executed, as far as polymorphism is concerned.)
Note that this means that overridden methods called from a constructor will be executed before the derived class's constructor body has had a chance to execute. This is dangerous. You should almost never call abstract or virtual methods from a constructor, for precisely this reason.
EDIT: Note that when you don't provide another constructor call to "chain" to using either : this(...) or : base(...) in the constructor declaration, it's equivalent to using : base(). So B's constructor is equivalent to:
public B() : base()
{
Print();
}
For more on constructor chaining, see my article on the topic.
Unlike C++ where calls of virtuals in the constructor are restricted to the definition within the class itself, the overrides are fully honored in C#'s constructors. The practice is frowned upon, and for a good reason (link), but it is still allowed: A's constructor calls the override supplied by B, producing the output that you see. This is the normal behavior of overriden virtual functions.
Because B override's the Print method. Your variable a is of type B, and B's Print method looks like this:
public override void Print()
{
Console.WriteLine("Print in B");
}
If you do not call a base class constructor, the default constructor for the base class will be called implicitly (MSDN).
You would not get the double output if you defined your class A constructors this way:
class A
{
public A()
{
// does nothing
}
public A(object a)
{
Print();
}
}
The reason it prints "Print in B" both times is that Print() is overridden in the class B so B.Print() is what is called by both constructors.
I think you can force the A.Print() to be called in the A constructor as follows:
class A
{
public A()
{
((A)this).Print();
}
}
Hope this helps.
Because you have an instance of B which overrides Print, so that overridden method gets called. Also, A's ctor will run, followed by B's which is why it gets printed twice.
So apparently you cannot use the virtual modifier with the override modifier.
virtual - a method that can be overridden
override - a method that is overriding a method of the same name in its parent's class
This leads me to believe that if I override a method in a child class, if that child has a child you can't override that method again.
And it is safe to say that if you put override and virtual in a method declaration you will get a compile error in C#.
However I can't understand why the code I made below works the way in which it does
using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("Drawing Object");
}
}
public class DrawDemo
{
public static int Main()
{
DrawingObject[] dObj = new DrawingObject[3];
dObj[0] = new DrawingObject();
dObj[1] = new Line();
dObj[2] = new LittleLine();
foreach (DrawingObject drawObj in dObj)
{
drawObj.Draw();
}
Console.Read();
return 0;
}
}
public class Line : DrawingObject
{
public override void Draw()
{// the method above me is in fact virtual because LittleLine overid it?
Console.WriteLine("I'm a Line.");
}
}
public class LittleLine : Line
{
public override void Draw()
{
Console.WriteLine("I'm a Little Line.");
}
}
Here's the output:
Drawing Object
I'm a Line.
I'm a Little Line.
So the draw method in Line looks as though it was overridden by LittleLine. Is this code not actually overriding it, or is the compiler doing some other trick? Or am I not understanding the context of virtual and override?
You can declare a certain method as virtual only once, but you can override it as many times as you want - an override is not final, and it does not limit classes that inherit from the first overriding class. The method that will eventually execute is the last one the overrides the virtual method. So your code does behave as expected.
C# is very verbose with regard to overriding - you have more specifiers than C++ or Java. It is so to let the programmer specify the exact intent:
You use virtual to specify a method can be overridden by subclasses.
You use override to specify you are overriding a method that you know is virtual (if it's not, the compiler will report an error).
You use sealed to prevent further overriding.
And you use new to hide instead of override.
This can be confusing and sometimes annoying, but it ensures you actually know what you're doing, and it makes your intention self-documented.
So apparently you cannot use the virtual modifier with the override modifiers.
Indeed. The method stays virtual unless you override it with a method which is also declared to be sealed. (You can only use the sealed modify on a method when you're overriding something.) From section 10.6.5 of the C# 4 spec:
When an instance method declaration includes a sealed modifier, that method is said to be a sealed method. If an instance method declaration includes the sealed modifier, it must also include the override modifier. Use of the sealed modifier prevents a derived class from further overriding the method.
I think you simply misunderstood how virtual works. It's not limited to one level of inheritance, as explained here, for example:
For every virtual method declared in or inherited by a class, there exists a most derived implementation of the method with respect to that class. The most derived implementation of a virtual method M with respect to a class R is determined as follows:
•If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.
•Otherwise, if R contains an override of M, then this is the most derived implementation of M.
•Otherwise, the most derived implementation of M with respect to R is the same as the most derived implementation of M with respect to the direct base class of R.
This behavior is right. If you don't want inherited class to override your virtual method, you can mark it "sealed" like this:
public class Line : DrawingObject
{
public sealed override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
After that LittleLine class won't be able to override Draw method.
virtual means your method is dispatched through a virtual method table. If a method's virtual, any reference to that method on a derived class has to go through the vtable. You can't non-virtualize it just because a derived class overrides it - what would happen if LittleLine was cast to DrawingObject? You still need to find the correct implementation, which wouldn't be DrawingObject's
It looks like it worked as intended.
dObj[0] = new DrawingObject();
dObj[1] = new Line();
dObj[2] = new LittleLine();
You're calling Draw() and in a loop
heres the output Drawing Object I'm a Line. I'm a Little Line
dObj[0].Draw() -> "Drawing Object"
dObj[1].Draw() -> "I'm a Line."
dObj[2].Draw() -> "I'm a Little Line"
So The draw method in Line looks as though it was Overrriden by
LittleLine
Yes, isn't that what you expected? The method was marked as Virtual at the base class and you've overridden it. If you want to 'add to it' you'll need to use some other pattern. A decorator perhaps.
This question already has answers here:
Difference between shadowing and overriding in C#?
(7 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.