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.
Related
If we have this class:
public class a{
public void b(){ Console.WriteLine("a"); }
}
And then this class:
public class c : a{
public override void b(){ Console.WriteLine("c"); }
}
If I do this:
a _a = new c();
_a.b();
What will happen? Which method will be called? The one from base type, or the overridden one?
What will happen? Which method will be called? The one from base type,
or the overridden one?
Firstly, you're not overriding the method b within class a from the class c because you haven't marked it as virtual (should give you a compile time error if you had tried it). However, if you mark the method within class a as virtual like below:
public class a
{
public virtual void b() { Console.WriteLine("a"); }
}
then the result that will be printed out will be "c". The reason is due to the overriding mechanism.
It is an error, the base class's method must be marked virtual, abstract or override.
In the event you add abstract or virtual to the base class's method in your example an call as you did, the overridden method will be executed -- that is the entire point of override.
If you don't want the base class's method to be virtual or abstract, you can use new on the subclass's method and it will be replaced, but not overridden. That is, the method b() of the class the reference _a is cast to will be executed, In your example, it would be method b on class a that would be executed.
There are three ways you can "reuse" a method.
Overriding a method requires that method to be marked abstract or virtual. When overriding a method the overridden method will be called no matter what. You can however call the base method like :
base.Method();
Overloading allows you to change the type and number of Parameters your method uses. So:
public int Method(int A);
can be overloaded as:
public int Method(double B);
Lastly you have new. This allows you to replace a Method in a derived class. If you have a method:
public int Method();
in a base class and you create a new method
public new int Method();
in a derived class your new method will be called in your derived class but the base classes method will be called if you cast your class back to the base class. Not a very clear explaination I know but I am short on time at the moment.
Hope this helps
Danny
If I have something like this:
class Base
{
public void Write()
{
if (this is Derived)
{
this.Name();//calls Name Method of Base class i.e. prints Base
((Derived)this).Name();//calls Derived Method i.e prints Derived
}
else
{
this.Name();
}
}
public void Name()
{
return "Base";
}
}
class Derived : Base
{
public new void Name()
{
return "Derived";
}
}
and use the following code to call it,
Derived v= new Derived();
v.Write(); // prints Base
then the Name method of base class gets called. but what would be the actual type of this keyword in the Write method? if that is of Derived type(as the Program control enters the first if block in Write method) then it is calling the base Name method, and why does the explicit casting,(Derived)this, change the call to the Name method of derived class?
this will always be of the derived class type.
The reason why in the call this.Name(); calls the base class Name() method is because Name is not defined as a virtual method, thus it is being linked in compile time when the compiler knows nothing about the actual type of this that it will have at this point.
One more note regarding the code above. Generally in product code referring to a Derived class from the Base class explicitly is really a bad practice as it breaks one of the OOP principles that the Base class should not be aware about the classes which inherit it. However, assuming that the code above was just used for C++ investigation then this is of course ok.
You should be using virtual and override if you want to access any overridden members in a derived class:
class Base
{
public void Write()
{
if (this is Derived)
{
this.Name();//calls Name Method of Base class i.e. prints Base
((Derived)this).Name();//calls Derived Method i.e prints Derived
}
else
{
this.Name();
}
}
public virtual void Name()
{
return "Base";
}
}
class Derived : Base
{
public override void Name()
{
return "Derived";
}
}
This is all your need. You do not need to and should not be checking the type from the base to handle logic. Any special logic should be be handled in the derived classes and probably want to mark methods up as virtual in the base and override in the derived classes.
class Base
{
public void Write()
{
SomeWriteMethod(Name());
}
public virtual void Name()
{
return "Base";
}
}
class Derived : Base
{
public override void Name()
{
return "Derived";
}
}
If you want the actual name of the class in Name(), you just need to call GetType().Name in the base and it will automatically work for any derived classes as GetType() returns you the actual instanced type of the instance. Just like GetType() is of the actual instance, this is also your actual instance so any special logic will be of that class' implementation.
this is actually a redundant call in your base class. Either you specify it or you don't -- you get the same result. The reason you see mixed results is because you used the new operator. new only works when you are working with that explicit type. It basically hides other implementations in the chain. And so, this being in the context of Base is going to give your Base.Name() where as if you had overridden, Derived.Name() would have been used instead.
MSDN: Knowing when to use override and new keywords
Here is an excellent answer about new -- Why does calling a method in my derived class call the base class method?
By casting ((Derived)this).Name(), you are explicitly setting it to the derived class. Since you have Write defined in the base class, this will point method calls to it. This behavior occurs because you have not overridden the base method and you are calling it from the base class.
Consider this code:
internal class Program
{
private static void Main(string[] args)
{
var student = new Student();
student.ShowInfo(); //output --> "I am Student"
}
}
public class Person
{
public void ShowInfo()
{
Console.WriteLine("I am person");
}
}
public class Student : Person
{
public void ShowInfo()
{
Console.WriteLine("I am Student");
}
}
in above code we don't use method hiding.
when create instance of student and call showinfo method my output is I am Student i don't use new keyword.
Why does not call parent method when we don't use method hiding?
No matter whether you are using the new keyword or not the base method is not virtual. So it is always the derived method that will get called. The only difference is that the compiler emits you a warning because the base method is hidden and you didn't explicitly used the new keyword:
'Student.ShowInfo()' hides inherited member 'Person.ShowInfo()'. Use the new keyword if hiding was intended.
The C# compiler is emitting this to warn you that you might have by mistake done that without even realizing it.
In order to fix the warning you should use the new keyword if this hiding was intentional:
public new void ShowInfo()
{
Console.WriteLine("I am Student");
}
If not, you should make the base method virtual:
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am person");
}
}
and then override it in the derived class:
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am Student");
}
}
Obviously in both cases you have the possibility to call the base method if you want that:
public override void ShowInfo()
{
base.ShowInfo();
Console.WriteLine("I am Student");
}
Actually, the new modifier has no effect at all from a program logic perspective.
The only effect the new modifier has is to document your intentions so that:
the compiler can warn you when appropriate (such as when using the new modifier in a declaration that does not hide an inherited member - or the opposite, when not using the new modifier even if the declaration does hide an inherited member)
other developers easier understand your code
What really matters to hiding/not hiding is whether you use the override modifier or not (which you can only use if the inherited member is virtual). If you don't use the override modifier, the inherited member is always hidden. In your example you don't use the override modifier, so you do hide the inherited member.
Note: Don't confuse the 'new modifier' with the 'new operator' or the 'new constraint'
It is using method hiding, it is just implicitly used. The new keyword should be used to explicitly show that you know you are hiding the method, however, your code will still compile and hide the method. Although this is definitely not recommended.
Student.ShowInfo() hides inherited member Person.ShowInfo()
you better check the compiler warnings
'ConsoleApplication5.Program.Student.ShowInfo()' hides inherited
member 'ConsoleApplication5.Program.Person.ShowInfo()'. Use the new
keyword if hiding was intended.
Using the same method signature ShowInfo means that you are going to hide the parent classes method. The new keyword is not required, it just lets the developer know that the current method is hiding another method in the parent class.
It is hiding which is why you get a warning saying that if you intentionally meant to hide it, you should use the new keyword. Check section 3.7.1.2 of the C# Language Spec Hiding through inheritance.
Name hiding through inheritance occurs when classes or structs
redeclare names that were inherited from base classes.
This type of name hiding takes one of the following forms:
•A
constant, field, property, event, or type introduced in a class or
struct hides all base class members with the same name.
•A method
introduced in a class or struct hides all non-method base class
members with the same name, and all base class methods with the same
signature (method name and parameter count, modifiers, and types).
•An indexer introduced in a class or struct hides all base class
indexers with the same signature (parameter count and types).
The reason is, the base classes methods are hidden when you redeclare it. It is called hiding through inheritance.
As others said method hiding is implicit whether you used new keyword or not. You can check with this piece of code -
private static void Main(string[] args)
{
Person student = new Student();
student.ShowInfo(); //output --> "I am person"
}
When you instantiate base class object with derived class, your derived method won't get called.
I'm getting a compilation error on following code:
public abstract class DbHandler<T>
{
public abstract bool Save(T obj);
...
}
and its implementing class:
public class SpaghettiTableDb : DbHandler<SpaghettiTable>
{
public bool Save(SpaghettiTable obj)
{
return false;
}
...
}
The error is :
'SpaghettiTableDb' does not implement inherited abstract member 'SeatPicker.DbHandler<SeatPicker.SpaghettiTable>.Save(SeatPicker.SpaghettiTable)'
But I think it does, so I'm not sure why I'm receiving this error.
(SpaghettiTable is just a class with some properties, nothing more)
Any help?
You need to use the override keyword. Otherwise you're not implementing the abstract base class and just creating a "new" separate method on the subclass.
public override bool Save(SpaghettiTable obj)
{
return false;
}
Think of abstract methods just like virtual methods that you override. The only difference is that you force subclasses to provide an implementation of that method whereas virtual methods provide their own implementation that subclasses can optionally override with their own implementation.
EDIT: Additionally, if you want to make your life easier in Visual Studio, you can right-click (or ctrl+.) on the inheritance declaration and choose "implement abstract class" (or something like that, I don't have VS with me right now) which will automatically create all the overridden methods for you.
public class SpaghettiTableDb : DbHandler<SpaghettiTable> //right-click on "DbHandler"
Alternatively, in the empty code space within your class, you can start typing "override", then the IntelliSense will list all overridable members from the base class and when you pick one it will automatically write a default implementation for you.
EDIT:
Just to extend on what you have in your code, without the override keyword, you are creating a new method that belongs to your subclass and not overriding the base class. When you call that method but from the context of using the base class, it won't call your subclass implementation since it doesn't override the base method.
Consider the following classes. (I'm using virtual instead of abstract just so it compiles and have it simpler)
public class BaseClass
{
public virtual void Print()
{
Console.WriteLine("base print");
}
public virtual void AnotherPrint()
{
Console.WriteLine("base another print");
}
}
public class SubClass : BaseClass
{
public override void Print()
{
Console.WriteLine("sub print");
}
public void AnotherPrint()
{
Console.WriteLine("sub another print");
}
}
Note that SubClass.AnotherPrint does not override BaseClass.AnotherPrint.
And when you use code like:
SubClass mySub = new SubClass();
mySub.Print(); //sub print
mySub.AnotherPrint(); //sub another print
BaseClass myBase = mySub;
myBase.Print(); //sub print
myBase.AnotherPrint(); //base another print
Note that through the code, mySub and myBase both point to the same object, but one is typed as SubClass and the other as BaseClass. When the runtime calls myBase.Print(), it can easily check the inheritance of the classes and see that SubClass has overridden the Print method and calls the SubClass implementation. However, since SubClass.AnotherPrint wasn't explicitly marked with override, the runtime/compiler considers that to be a completely different method with no link to the BaseClass.AnotherPrint method. Thus the runtime sticks with the base class implementation. When your instance is typed as the SubClass though, the compiler does see that you're pointing to that new method and essentially not to the base implementation.
You need to use the override keyword when implementing abstract methods or overriding virtual methods.
public override bool Save(SpaghettiTable obj)
{
return false;
}
In C# what does the term shadowing mean? I have read this link but didn't fully understand it.
Shadowing hides a method in a base class. Using the example in the question you linked:
class A
{
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A
{
public new int Foo() { return 1;}
public override int Bar() {return 1;}
}
Class B overrides the virtual method Bar. It hides (shadows) the non-virtual method Foo. Override uses the override keyword. Shadowing is done with the new keyword.
In the code above, if you didn't use the new keyword when defining the Foo method in class B, you would get this compiler warning:
'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.
Overriding : redefining an existing method on a base class
Shadowing : creating an entirely new method with the same signature as one in a base class
Suppose I have a base class that implements a virtual method:
public class A
{
public virtual void M() { Console.WriteLine("In A.M()."); }
}
I also have a derived class that also defines a method M:
public class B : A
{
// could be either "new" or "override", "new" is default
public void M() { Console.WriteLine("In B.M()."); }
}
Now, suppose I write a program like this:
A alpha = new B(); // it's really a B but I cast it to an A
alpha.M();
I have two different choices for how I want that to be implemented. The default behavior is to call A's version of M. (This is identical to the behavior if you applied the "new" keyword to B.M().)
This is called "shadowing" when we have a method with the same name but a different behavior when called from the base class.
Alternately, we could have specified "override" on B.M(). In this case, alpha.M() would have called B's version of M.
Shadowing consist on hiding a base class method with a new definition in a child class.
The difference between hiding and overriding has to do with the way methods are invoked.
That way, when a virtual method is overridden, the call address for the method call table of the base class is replaced with the address of the child routine.
On the other hand, when a method is hidden, a new address is added to the method call table of the child class.
When a call is made to the method in question:
The method call table class type is obtained, if we are invoking with a reference to the base class then the base class method table is obtained, if we have a reference to the child class, then the child class method table is obtained.
The method is searched in the table, if it's found then the invocation takes place, otherwise the base class method table is searched.
If we invoke the method with a reference to the child class then the behavior is the same, if the method has been overridden, the method address will be found in the base class, if the method was hidden the method address will be found on the child class, and since it has been already found, base class table will not be searched.
If we invoke the method with a reference to the base class then behavior changes. When overriding, as the method address overwrites base class entry, we will call the child method, even when holding a reference to the base class. With shadowing, the base class method table (which is the only one visible as we hold a reference to the base class) contains the virtual method address, and therefore, the base class method will be called.
In general shadowing is a bad idea, as it introduces a difference on the behavior of an instance depending on the reference we have to it.
Expanding on Kent's correct answer
When disambiguating when which method will be called, I like to think of shadowing vs. overriding with the following
Shadowing: The method called depends on the type of the reference at the point the call is made
Overriding: The method called depends on the type of the object at the point the call is made.
Here's an MSDN article on Shadowing. The language examples are in Visual Basic (unfortunately there is no equivalent C# page on MSDN), but it deals generally with the concepts and hopefully should help you understand anyway.
Edit: Seems like there is a C# article on shadowing, except that it's called hiding in C#. Also, this page offers a good overview.
If you want to hide Base class method , Use override in base [virtual method in base]
if you want to hide Child class method , Use new in base [nonvirtual method in base]->shadow
Base B=new Child()
B.VirtualMethod() -> Calls Child class method
B.NonVirtualMethod() -> Calls Base class method
Overriding: same name and exactly the same parameters, implemented
differently in sub classes.
If treated as DerivedClass or BaseClass, it used derived method.
Shadowing: same name and exactly the same parameters, implemented differently in sub classes.
If treated as DerivedClass, it used derived method.
if treated as BaseClass, it uses base method.
Hope this brief explanation helps.
Shadowing - Replaces the complete element of the parent class
class InventoryAndSales
{
public int InvoiceNumber { get; set; }
}
//if someone calls for this class then the InvoiceNumber type is now object
class NewInventoryAndSales : InventoryAndSales
{
public new object InvoiceNumber { get; set; }
}
Overriding - Only replaces the implementation. It doesn't replace the data type it doesn't replace like for example you have a variable it doesn't convert it into a method so if there is a method it will use that method and only changed the implementation
class InventoryAndSales
{
public virtual int GetTotalSales(int a, int b)
{
return a + b;
}
}
class NewInventoryAndSales : InventoryAndSales
{
//it replaces the implementation in parent class
public override int GetTotalSales(int a, int b)
{
return a * b;
}
}
Shadowing isn't something I'd be worried about understanding or implementing unless it "fits" the problem really well. I've seen it used improperly and cause weird logic bugs much more often than being used correctly. The big cause, I think, is when the programmer forgets to put overrides in a method signature then the compiler warning will suggest the new keyword. I've always felt that it should recommend using override instead.
private static int x = 10;
static void Main(string[] args)
{ int x = 20;
if (Program.x == 10)
{
Console.WriteLine(Program.x);
}
Console.WriteLine(x);}
Output:
10
20