Given three parent/child classes, like this:
class A {
public virtual void doSomething() {
//do things
}
}
class B : A {
public override /*virtual?*/ void doSomething() {
//do things
base.doSomething();
}
}
class C : B {
public override void doSomething() {
//do things
base.doSomething();
}
}
Should class B's doSomething() method have both override and virtual in its signature, since it also is overridden by the C class, or should only class A have virtual in its doSomething() method signature?
You don't need to (read: you can't) mark a method as virtual, if it has already been marked as virtual in one of the super classes.
The method will remain virtual throughout the inheritance tree until a subclass marks it as sealed. A sealed method cannot then be overridden by any of the subclasses.
From MSDN:
You cannot use the new, static, or virtual modifiers to
modify an override method.
Also,
The overridden base method must be virtual, abstract, or override.
Meaning that you can override a method that is already marked as override.
Related
My friend asks me if an abstract method could have virtual modifier. And I said, No.
Because, an abstract method is implicitly also a virtual method, it cannot have the modifier virtual.
But while reading one of the MSDN articles, I have seen this:
...
If a virtual method is declared abstract, it is still virtual to any
class inheriting from the abstract class. A class inheriting an
abstract method cannot access the original implementation of the
method—in the previous example, DoWork on class F cannot call DoWork
on class D. In this way, an abstract class can force derived classes
to provide new method implementations for virtual methods....
I can't understand first sentence correctly. Could you please, explain me what they wants to say?
Thanks.
It becomes clearer when you look at the code example directly above the quoted paragraph:
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}
public abstract class E : D
{
public abstract override void DoWork(int i);
}
The virtual method D.DoWork is inherited by E, and, there, declared abstract. The method is still virtual, it has just become abstract as well.
As you correctly state, an abstract method is always virtual. If your friend is still unconvinced, here's an official quote for that:
An abstract method is implicitly a virtual method.
Abstract classes may override virtual members with abstract ones:
public class B
{
public virtual void M() { }
}
public abstract class D : B
{
public abstract override void M();
}
public abstract class D2 : D
{
public override void M() { }
}
The sentence says that D2 must override void M(), because it is declared abstract in D. If it were declared as D2 : B, this would be optional, but as it stands, D2 has to comply with the contracts specified in D, but M() will also behave like any other member overriding a "normal" virtual member, since M() is both virtual and abstract.
How do I prevent a method from being overridden in a derived class?
In Java I could do this by using the final modifier on the method I wish to prevent from being overridden.
How do I achieve the same in C#?
I am aware of using sealed but apparently I can use it only with the override keyword?
class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
So in the above example I can prevent the methodB() from being overridden by any classes deriving from class B, but how do I prevent class B from overriding the methodB() in the first place?
Update: I missed the virtual keyword in the methodB() declaration on class A when i posted this question. Corrected it.
You don't need to do anything. The virtual modifier specifies that a method can be overridden. Omitting it means that the method is 'final'.
Specifically, a method must be virtual, abstract, or override for it to be overridden.
Using the new keyword will allow the base class method to be hidden, but it will still not override it i.e. when you call A.methodB() you will get the base class version, but if you call B.methodB() you will get the new version.
As you mentioned, you can prevent further overriding of MethodB in class B by using sealed with override
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
Use of the sealed modifier along with override prevents a derived class from further overriding the method.
If you do not want methodB in class A to be overridden by any child classes, do not mark that method virtual. Simply remove it. virtual keyword enable the method to be overridden in child classes
public void methodA()
{
}
Use sealed keyword on your classes to prevent further overriding of the class
In C#, a function not marked virtual (which also includes overrides of virtual functions) is effectively sealed and cannot be overridden. So, your example code actually won't compile because the override keyword is not valid unless there is a method marked virtual with the same signature in a base class.
If A.methodB() were marked virtual, then you could override the method from A, but prevent it being further overridden in classes deriving more indirectly, using the sealed keyword exactly as you have shown.
One thing to keep in mind is that while method overriding can be prevented, method hiding cannot. Given your current definition of class A, the following definition of class B is legal and there's nothing you can do about it:
class B:A
{
public new void methodB()
{
//code
}
}
The new keyword basically "breaks" the inheritance/overriding hierarchy as it pertains to this one method; any reference to a class B, treated as a class B (or any further derived type) will use the implementation from class B and ignore the one from class A unless B's implementation specifically calls back to it. However, if you were to treat an instance of class B as a class A (by casting it or passing it as a parameter), then the "new" implementation is ignored.
This differs from overriding, where a class B that is being treated as a class A and truly overrides a virtual methodB would still use class B's override of the method. Also understand that method hiding is inferred (though you will get a compiler warning); if you declare a method with the same signature in a derived class and do not specify either new or override, the base class method will be hidden.
In a base class, the sealed keyword is only used to prevent a class from being derived, but in inherited classes it can be used to prevent another inherited class from overriding the method.
To prevent a base class method from being overridden, just do not specify it as virtual. In the example you provided, class B could not override methodB because methodB was not marked as virtual on the original class.
this will compile:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
this will not:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
EDITTED: clarified and corrected my original statement about the sealed keyword
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.
The need for virtual is dictated by polymorphism. Think about what happens when you redefine a method in a subclass using new:
class Parent
{
void Foo() { Console.WriteLine("Parent"); }
virtual void Bar { Console.WriteLine("Parent"); }
}
class Child : Parent
{
new void Foo() { Console.WriteLine("Child"); } // another method Foo
override void Bar { Console.WriteLine("Child"); }
}
var child = new Child(); // a Child instance
var parent = (Parent)child; // same object, but statically typed as Parent
c.Bar(); // prints "Child"
p.Bar(); // again, prints "Child" -- expected virtual behavior
c.Foo(); // prints "Child"
p.Foo(); // but this prints "Parent"!!
For this reason, classes that are intended to be derived from (i.e. not sealed) should always mark the methods that can be overridden as virtual -- otherwise there will be confusing runtime behavior like above. There's no difference if the parent implementation actually does anything or not; the point is that it behaves differently.
ok, by declaring the method as virtual (and not wishing to override the method in the subclass), you'd be entering the world of method hiding if you were to introduce a method with the same name into the subclass. You have to define it as thus:
public abstract class A
{
public virtual string GetName()
{
return null;
}
}
public class B : A
{
//assume there are some defined properties.
public new string GetName()
{
return FirstName;
}
}
I'd recommend that you think of the abstract override approach:
public abstract class A
{
public abstract string GetName()
}
// to override
public class B : A
{
//assume there are some defined properties.
public override string GetName()
{
return FirstName;
}
}
this would be quite different. I would strongly recommend that you just override the abstract method in the subclass.
However, here's a quick ref on the subject (old but a good read):
http://www.akadia.com/services/dotnet_polymorphism.html
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?
You can use an abstract methods, that have no body, but they if you derive from that class you must to override that method. All abstact methods have to be overriden in child class.
2) If (1) is incorrect, am I right in thinking that every virtual
method must be overridden in the subclass using it....
No, instead, you can use a virtual keyword to have an implementation inside that, but do not making override in a child class mandatory. Gives you more flexibility, from that point of view.
Usauly they use abstract to create rigid constrains for childs, so every child derived from it must implement specified member of base class.
That's exactly the difference between a virtual and an abstract method:
A virtual method can be overridden by derived classes if the choose to. A virtual method may or may not have a default implementation for inheritors to call into, which is done using the base keyword.
An abstract method must be overridden by derived classes. Its constraints are:
It can only be defined in an abstract class.
It cannot have an implementation, since it's up to the inheritors to define its behavior.
Why do we use override and virtual if it gives the same effect when we dont use override and virtual?
example 1:
class BaseClass
{
public virtual string call()
{
return "A";
}
}
class DerivedClass : BaseClass
{
public override string call()
{
return "B";
}
}
output : B
Example 2:
class BaseClass
{
public string call()
{
return "A";
}
}
class DerivedClass : BaseClass
{
public string call()
{
return "B";
}
}
and the output is still the same:
output : B
to run the test:
class Program
{
static void Main(string[] args)
{
DerivedClass dc = new DerivedClass();
Console.WriteLine(dc.call());
Console.ReadKey();
}
}
Does the compiler add virtual and override automatically at compile time?
I would be pleased if someone would explain to me the reason for using virtual and override.
(note, I'm quietly ignoring the compile errors)
Now do:
BaseClass obj = new DerivedClass();
Console.WriteLine(obj.call());
Without virtual, this will print A, when actually a DerivedClass should be writing B. This is because it has simply called the BaseClass implementation (since obj is typed as BaseClass, and no polymorphism is defined).
Virtual and override are a base mechanism of inheritance in object oriented programming.
This is perhaps the most important thing to understand when you use classes in a language like C# or Java.
http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
Inheritance allow you to reuse code adding new fields, properties and methods or replacing methods and properties of previously defined classes.
Virtual and Override allow you to replace the content of a method, and when i say replace, i say replace.
I would propose you a nice example.
public class MyClassEnglish
{
public virtual string SomethingToSay()
{
return "Hello!";
}
public void WriteToConsole()
{
Console.WriteLine(this.SomethingToSay());
}
}
public class MyClassItalian :
MyClassEnglish
{
public override string SomethingToSay()
{
return "Ciao!";
}
}
int main()
{
MyClassItalian it = new MyClassItalian();
it.WriteToConsole();
}
If you omit virtual and override, MyClassItalian will print out "Hello!" and not "Ciao!".
In your example you show a Shadowing technique, but the compiler should give you a warning.
You shoul add the "new" keyword if you want to hide a method in a base class.
Hiding a method is not overriding! Is just hiding.
One possible use that comes into my mind is that it can be used when you need some kind of optimization for example.
public abstract class MySpecialListBase
{
public int Count()
{
return this.GetCount();
}
protected abstract int GetCount();
}
public sealed class MySpecialArrayList : MySpecialListBase
{
int count;
public new int Count()
{
return this.count;
}
protected override int GetCount()
{
return this.count;
}
}
Now...
You can use MySpecialListBase in all your code, and when you call the Count() it will call the virtual method GetCount().
But if you use just MySpecialArrayList it will call the optimized Count() that is not virtual and that just return a field, increasing performances.
// This works with all kind of lists, but since it is a more general purpose method it will call the virtual method.
public void MyMethod(MySpecialListBase list)
{
Console.WriteLine(list.Count());
}
// This works only with MySpecialArrayList, and will use the optimized method.
public void MyMethod(MySpecialArrayList list)
{
Console.WriteLine(list.Count());
}
Best example I can think of where this is useful is when you create your own object(class) and you have to add a list of that object to a combobox.
When you add your object to the combobox you want to be able to control what text is displayed for each item. Object.toString is a virtual method. http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx and because of this you can override that method and set .toString to display the correct information about your object by overriding it.
public MyClass()
{
private int ID;
public override string ToString()
{
return "My Item:" + ID;
}
}
Method Overriding:
Where you define or implement a virtual method in a parent class and then replace it in a descendant class.
When you decide to declare a method as virtual, you are giving permission to derived classes to extend and override the method with their own implementation. You can have the extended method call the parent method's code too.
In most OO languages you can also choose to hide a parent method. When you introduce a new implementation of the same named method with the same signature without overriding, you are hiding the parent method.
C# Overriding
In C#, you specify a virtual method with the virtual keyword in a parent class and extend (or replace) it in a descendant class using the override keyword.
Use the base keyword in the descendant method to execute the code in the parent method, i.e. base.SomeMethod().
Syntax Example:
class Robot
{
public virtual void Speak()
{
}
}
class Cyborg:Robot
{
public override void Speak()
{
}
}
Override Details
You cannot override a regular non-virtual method, nor a static method.
The first version of the parent method must be virtual or abstract.
You can override any parent method marked virtual, abstract, or override (already overridden).
The methods must have the same signature.
The methods must have the same visibility (the same access level).
Use the base keyword to refer to the parent class as in base.SomeMethod().
C# Override Example
The following code snippet demonstrates using virtual and override to override a parent method in a descendant class.
using System;
class Dog
{
public virtual void Bark()
{
Console.WriteLine("RUFF!");
}
}
class GermanShepard:Dog
{
public override void Bark()
{
Console.WriteLine("Rrrrooouuff!!");
}
}
class Chiuaua:Dog
{
public override void Bark()
{
Console.WriteLine("ruff");
}
}
class InclusionExample
{
public static void Main()
{
Dog MyDog=new Dog();
MyDog=new GermanShepard();
MyDog.Bark(); // prints Rrrrooouuff!!
MyDog=new Chiuaua();
MyDog.Bark(); // prints ruff;
}
}
Hiding a Method with New
Use the new keyword to introduce a new implementation of a parent method (this hides the parent method). You can hide a method without using new but you will get a compiler warning. Using new will suppress the warning.
The new and override modifiers have different meanings. The new modifier creates a new member with the same name, signature, and visibility and hides the original member. The override modifier extends the implementation for an inherited member and allows you to implement inheritance-based polymorphism.
Avoid Introducing New Members: Sometimes there are clear reasons to introduce a new method with the same name, signature, and visibility of a parent method. In those clear cases, introducing a new member is a powerful feature. However, if you do not have a clear reason, then avoid introducing a new version of a method by naming the new method something unique and appropriate.
class Robot : System.Object
{
public void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
new public void Speak()
{
MessageBox.Show("hi");
}
}
Calling the Base Class Version
A common task In OO is to extend a method by first executing the parent method code and then adding code. Use the base keyword to refer to the parent class as in base.SomeMethod().
class Robot : System.Object
{
public virtual void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
public override void Speak()
{
base.Speak();
MessageBox.Show("hi");
}
}
I believe I want a some methods and properties of a class to be unoverridable and use the base's implementation in all derived classes. How to achieve this? sealed keyword doesn't seem to work and says "method can not be sealed because it is not an override".
Members are sealed by default in C# - unless they're marked as virtual, they can't be overridden in derived classes anyway.
They can be shadowed in derived classes, admittedly:
public new void SomeMethod()
{
}
... but that's not the same as overriding. There's no way you can prevent this, but if a caller uses a compile-time type of the base class, they won't end up calling this accidentally anyway.
If you could give us more details of exactly what you're trying to prevent (from both the caller's POV and the code being called) we may be able to help more.
A method that is not already an override will not be overridable unless you mark it as virtual. So it sounds like in your case no action is needed.
class A
{
public void B() {} // can't override
public virtual C() {} // can override
public virtual D() {} // can override
}
The sealed modifier only applies when a method is already an override of a member in the base class. This allows you to prevent overrides in subclasses of that class.
class A1 : A
{
public void B() {} // shadows A.B. Not a virtual method!
public override C() {} // overrides A.C, subclasses can override
public override sealed D() {} // overrides A.D, subclasses cannot override
// (but can shadow)
}
This isn't possible. A derived class can always use the new keyword to hide (not override) its parents methods. The sealed keyword simply stops the derived class from overriding a virtual method, but it could still use new to hide the base method.
The "sealed" keyword can only be used, if you override a method that is virtual, but don't want a class deriving from your implementation to override it again. Declaring the method not virtual is all you need.
As other pointed out that there is in fact a "new" keyword, which allows hiding the method. But as long as you use a reference of your base class, your base method is always called:
class BaseClass
{
public void Foo() { Console.WriteLine("Foo"); }
}
class Derived : BaseClass
{
public new void Foo() { Console.WriteLine("Bar"); }
}
public static void Main()
{
Derived derived = new Derived();
derived.Foo(); // Prints "Bar"
BaseClass baseClass = derived;
baseClass.Foo(); // Prints "Foo"
}
Since providing a base-class only makes sense, as long as you use a "BaseClass"-pointer everywhere, your method cannot be hidden.
This is precisely what sealed keyword is for.
http://msdn.microsoft.com/en-us/library/ms173150.aspx
A class member, method, field,
property, or event, on a derived class
that is overriding a virtual member of
the base class can declare that member
as sealed. This negates the virtual
aspect of the member for any further
derived class. This is accomplished by
putting the sealed keyword before the
override keyword in the class member
declaration.
If you've overridden a method from base class than use sealed.
If you've declared a method in the class and don't want it to be overridden in any derived classes than don't mark it as virtual. Only virtual members can be overridden.