I thought I had this nailed, and then I go and look at some source at work and am left wondering why there are so many contradictions in what I read from msdn and what I am seeing in source....
My understanding is that the virtual keyword can be used in method declarations to allow any deriving classes to override it.
The override keyword would then need to be used in the derived class when implementing the superclass' virtual method....
For example:
public abstract class A
{
public virtual string GetName();
}
public class B:A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
I have a few questions:
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
EDIT:
You're right my code will not compile... I want to know why....I uinderstand your answers but then I saw this:
public abstract class RequestHandler<TRequest, TResponse> : RequestHandler, IRequestHandler<TRequest>, IRequestHandler, IDisposable, ITypedRequestHandler
where TRequest : global::Agatha.Common.Request
where TResponse : global::Agatha.Common.Response, new()
{
protected RequestHandler();
public virtual void AfterHandle(TRequest request);
public virtual void BeforeHandle(TRequest request);
public override Response CreateDefaultResponse();
public TResponse CreateTypedResponse();
public override Response Handle(Request request);
public abstract Response Handle(TRequest request);
}
The above doesnt cause the compiler to complain...
Firstly the above code is invalid. A virtual method still has to have a body with a default implementation. to do what you have done above you would need to use the abstract
keyaord instead of virtual.
abstract
means that there is no method body provided but that any class deriving from it must implement this method (unless it is abstract too).
I think this pretty much answers your questions....
If it has no implementation then it cannot be virtual, it must be abstract. If it has an implementation that just does nothing then that must be implemented.
The whole point of a virtual class is that it has default behaviour so you can choose whether or not to override it. If it were abstract then you would have to override it (unless you were deriving another abstract class).
Is it really necessary to define a method as virtual if it has no implementation?
You can make the method abstract (it will implicitly make it virtual).
Surely it can just be overwritten in the subclass without the use of virtual and override?
If you just "overwrite" it without explicitly overriding it, it won't be the same method, and calling the method on a variable of the base class won't call the derived method (it won't participate in polymorphism). You would just be "hiding" the method of the base class (the compiler actually warns you about this, if it's really what you want to do you must use the new
modifier.)
An example will make it clearer:
class B
{
public virtual void M() { Console.WriteLine("B.M") };
}
class D1 : Base
{
// Hides the base method
public new void M() { Console.WriteLine("D1.M") };
}
class D2 : Base
{
// Overrides the base method
public override void M() { Console.WriteLine("D2.M") };
}
...
D1 d1 = new D1();
d1.M(); // Prints "D1.M"
B b1 = d1;
b1.M(); // Prints "B.M", because D1.M doesn't override B.M
D2 d2 = new D1();
d2.M(); // Prints "D2.M"
B b2 = d2;
b2.M(); // Also prints "D2.M", because D2.M overrides B.M
If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
No, only if it's abstract... a virtual method can have an implementation, and in that case derived classes are not forced to override it.
1) Is it really necessary to define a method as virtual if it has no implementation? Surely it can just be overwritten in the subclass without the use of virtual and override?
As said in other answers, virtual
methods need to have implementations. You are confusing it with abstract
.
If you were asking whether virtual
methods which do have an implementation need to be declared virtual
: In C#, yes, it is necessary. In Java, you can override any old method. It was a C# design decision to require overriding to be specifically allowed with the virtual
keyword, so that methods cannot be overridden unless intended by the programmer.
If the programmer has not expressed intent by not using virtual
, you can still "override" methods, with the new
keyword. However, this works a bit differently. Hopefully this code will help illustrate the concept:
class Program
{
static void Main(string[] args)
{
var baseC = new BaseClass();
var extC = new ExtClass();
var lazyC = new LazyClass();
Console.WriteLine(baseC.NewMethod());
Console.WriteLine(baseC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(extC.NewMethod());
Console.WriteLine(extC.VirtualOverrideMethod());
Console.WriteLine("---");
Console.WriteLine(((BaseClass) extC).NewMethod());
Console.WriteLine(((BaseClass) extC).VirtualOverrideMethod()); // Redundant typecast
Console.WriteLine("---");
Console.WriteLine(lazyC.VirtualOverrideMethod());
Console.ReadKey();
}
public class BaseClass
{
public BaseClass()
{
}
public string NewMethod()
{
return "NewMethod of BaseClass";
}
public virtual string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of BaseClass";
}
}
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
class LazyClass : BaseClass
{
}
}
Output:
NewMethod of BaseClass
VirtualOverrideMethod of BaseClass
---
NewMethod of ExtClass
VirtualOverrideMethod of ExtClass
---
NewMethod of BaseClass
VirtualOverrideMethod of ExtClass
---
VirtualOverrideMethod of BaseClass
2) If (1) is incorrect, am I right in thinking that every virtual method must be overridden in the subclass using it....
Not at all. virtual
is a way of saying, "it's okay if you want to override this method". In fact, I included LazyClass
in my code above to show this.
The above doesnt cause the compiler to complain...
I haven't used interfaces much, but that looks like one. In my code, if I change
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
to:
class ExtClass : BaseClass
{
public new string NewMethod()
{
return "NewMethod of ExtClass";
}
public override string VirtualOverrideMethod()
{
return "VirtualOverrideMethod of ExtClass";
}
}
I get:
error CS0501: 'OverrideTest.Program.ExtClass.VirtualOverrideMethod()' must declare a body because it is not marked abstract, extern, or partial
From Visual Studio 2010. The same goes for the virtual
method of my BaseClass
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With