I'm pretty confused between some concepts of OOP: virtual
, override
, new
and sealed override
. Can anyone explain the differences?
I am pretty clear that if the derived class method is to be used, one can use the override
keyword so that the base class method will be overriden by derived class. But I'm not sure about new
, and sealed override
.
Now First thing First
Now the keywords are all about Polymorphism
virtual
in base class and override inDerived
will give D(Polymorphism).override
withoutvirtual
inBase
will give error.virtual
will write 'B' with warning (because no polymorphism is done).new
before that simple method inDerived
.new
keyword is another story, it simply hides the warning that tells that the property with same name is there in base class.virtual
ornew
both are same except new modifiernew
andoverride
cannot be used before same method or property.sealed
before any class or method lock it to be used in Derived class and it gives a compile time error.The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it: Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed.
By default a method cannot be overridden in a derived class unless it is declared
virtual
, orabstract
.virtual
means check for newer implementations before calling andabstract
means the same, but it is guaranteed to be overridden in all derived classes. Also, no implementation is needed in the base class because it is going to be re-defined elsewhere.The exception to the above is the
new
modifier. A method not declaredvirtual
orabstract
can be re-defined with thenew
modifier in a derived class. When the method is called in the base class the base method executed, and when called in the derived class, the new method is executed. All thenew
keywords allows you to do is to have two methods with the same name in a class hierarchy.Finally a
sealed
modifier breaks the chain ofvirtual
methods and makes them not overridable again. This is not used often, but the option is there. It makes more sense with a chain of 3 classes each deriving from the previous oneif
A
has anvirtual
orabstract
method, that isoverridden
inB
, then it can also preventC
from changing it again by declaring itsealed
inB
.sealed
is also used inclasses
, and that is where you will commonly encounter this keyword.I hope this helps.
Any method can be overridable (=
virtual
) or not. The decision is made by the one who defines the method:Now you can override those methods that are overridable:
But you can't override the
GetPersonType
method because it's not virtual.Let's create two instances of those classes:
When non-virtual method
GetPersonType
is called byFiend
instance it's actuallyPerson.GetPersonType
that is called:When virtual method
GetName
is called byFriend
instance it'sFriend.GetName
that is called:When virtual method
GetName
is called byPerson
instance it'sPerson.GetName
that is called:When non-virtual method is called the method body is not looked up - compiler already knows the actual method that needs to be called. Whereas with virtual methods compiler can't be sure which one to call, and it is looked up at runtime in the class hierarchy from down to up starting at the type of instance that the method is called on: for
friend.GetName
it looks starting atFriend
class and finds it right away, forperson.GetName
class it starts atPerson
and finds it there.Sometimes you make a subclass, override a virtual method and you don't want any more overrides down in the hierarchy - you use
sealed override
for that (saying you are the last one who overrides the method):But sometimes your friend Mike decides to change his gender and thus his name to Alice :) You could either change original code or instead subclass Mike:
Here you create a completely different method with the same name (now you have two). Which method and when is called? It depends on how you call it:
When you call it from
Alice
's perspective you callAlice.GetName
, when fromMike
's - you callMike.GetName
. No runtime lookup is made here - as both methods are non-virtual.You can always create
new
methods - whether the methods you are hiding are virtual or not.This applies to properties and events too - they are represented as methods underneath.