Polymorphism is the ability of an object oriented language (C# in this context) to allow a base class to define a set of members (formally termed the polymorphic interface) that are available to all descendents. A class’s polymorphic interface is constructed using any number of virtual or abstract members.
A virtual member is a member in a base class that defines a default implementation that may be changed (overridden) by a derived class.
In contrast, an abstract method is a member in a base class that does not provide a default implementation, but does provide a signature. When a class derives from a base class defining an abstract method, it must be overridden by a derived type.
In either case (virtual or abstract), when derived types override the members defined by a base class, they are essentially redefining how they respond to the same request.
Method Overriding – Method Overriding is a process in which a derived class can define its own version of a method, which was originally defined by its base class.
Virtual Keyword – The virtual keyword indicates that the base class wants to define a method which may be (but does not have to be) overridden by a derived class. A virtual method provides a default implementation that all derived types automatically inherit. If a child class so chooses, it may override the method but does not have to.
Note: Subclasses are never required to override virtual methods.
Override Keyword – The override keyword is used by a derived class to to change the implementation details of a virtual method (defined in the base class). Each overridden method is free to leverage the default behavior of the parent class using the base keyword.
Sealed Keyword – The sealed keyword is basically applied to classes to prevent other types from extending its behavior via inheritance.
It can also be applied to virtual methods to prevent derived types from overriding those methods. Ex.
public override sealed void GiveBonus(float amount)
Any effort to override the above sealed method in the derived class will generate compile time error.
Abstract Classes – The abstract keyword can be used in the class definition to prevent direct creation of an instance of the class. Although abstract classes cannot be created directly, it is still assembled in memory when derived classes are created. Thus, it is perfectly fine for abstract classes to define any number of constructors that are called indirectly when derived classes are allocated.
An abstract class can define any number of abstract members (members that does not supply a default implementation, but must be accounted for by each derived class).
The polymorphic interface of an abstract base class simply refers to its set of virtual and abstract methods. Methods marked with abstract are pure protocol. They simply define the name, return type (if any), and parameter set (if required).
If you do not override an abstract method (of the base abstract class) in the derived class, the derived class will also be considered abstract, and would have to be marked abstract with the abstract keyword.
Although it is not possible to directly create an instance of an abstract base class, you can freely store references to any subclass with an abstract base variable.