I have knowledge of java and have been learning c# for the last couple of days. Now I have come across the "virtual" keyword which, as suggested at this link, is used to allow the corresponding methods, properties etc. to be overriden in the subclasses. Now I think we can override methods even without using the "virtual" keyword. Then why it is necessary?
问题:
回答1:
You need the virtual
keyword if you really want to override
methods in sub classes. Otherwise the base implementation will be hidden by the new implementation, just as if you had declared it with the new
keyword.
Hiding the methods by "overriding" them without the base method being declared virtual
leaves you without polymorphism, that means: if you "cast" a specialized version to the "base" version and call a method, always the base classes implementation will be used instead of the overridden version - which is not what you'd expect.
Example:
class A
{
public void Show() { Console.WriteLine("A"); }
}
class B : A
{
public void Show() { Console.WriteLine("B"); }
}
A a = new A();
B b = new B();
a.Show(); // "A"
b.Show(); // "B"
A a1 = b;
a1.Show(); // "A"!!!
回答2:
virtual
is a way of defining that a method has a default implementation, but that that implementation may be overriden in a child class. Other than by using virtual, you cannot override a method directly without using the new
keyword (which is generally bad practice).
A good example of the implementation of virtual
is the ToString()
method. Every object in C# is guaranteed to be able to call ToString()
because every object inherits from the base System.Object
class, which contains a virtual method ToString()
. Derived classes can override this however, and provide their own implementation which may be more useful to the users of the object.
Update: I recently wrote a blog post which goes into this topic in a bit of depth. Check it out here.
回答3:
Now I think we can override methods even without using the "virtual" keyword.
No, you can't. Contrary to Java, in C# members are sealed by default and you cannot override them unless you marked them with the virtual
keyword.
回答4:
Take a look at this example:
void Main()
{
var o1 = new S();
Console.WriteLine(((B)o1).m1());
}
public class B
{
public virtual string m1() {
return "m1";
}
}
public class S : B
{
override public string m1() {
return "overridden m1";
}
}
In this example the subclass S
is instantiated and assigned to object variable o1
.
In the Console.WriteLine
statement's parameter it is being cast into the base class B
, then method m1
is called.
Because we have used virtual
in the base class B
and override
in the subclass S
, we're getting
overridden m1
as output. If you remove virtual
in the method declaration of m1
in B
and override
in the subclass S
then you're getting
m1
as output, which means that the cast also has the effect that the original declaration of method m1
in the base class B
is used.
N.B. If you're using the new
keyword in subclass S
, such as
new public string m1() {
return "overridden m1";
}
assuming that the virtual
keyword in the base class B
is absent, you're getting the output
m1
as well. If you would not cast it to B
, the new method would be used. This is called shadowing (or hiding) a method (the original method of the base class).
Summary:
To override a method, which should be effective also if you cast to the base class, use the
virtual
keyword in the base class andoverride
in the sub class.If you intend to override the method, which should be active in the sub class only, use the
new
keyword in the sub classes method declaration. As you have seen it works also without it, but it is better if it is there so everyone knows that this is a new version of the method.