Abstract or Virtual ?
Tags: beginners, csharp, oop
Published: 2020-04-23 15:58:25

We have come across abstract and virtual methods while programming and I often get startled when I see these two keywords. Whenever I try to look up for them a lot of "tabular comparisons" are being thrown at me, distinguishing between the two without highlighting why they are so ? 

I try to put together my understanding below. 

Abstract and virtual methods are a part of a concept called as ***polymorphism*** from object oriented programming. ***Polymorphism*** is further derived from the idea of ***Inheritance***.
Why do we need Inheritance ? Inheritance is supposed to be the best feature of ***OOP***. We can extend and reuse the capabilities of a class further as per the business needs i.e. writing less code ! How does ***polymorphism*** fits into this ? Say we have a class which outlines how a pizza should be . It also has a method called Prepare, data properties for the pizza name and price. In its most basic form, this method would output a plain pizza.
```javascript
 public class Pizza
    {
        public string Name { get; set; }
        public int Price { get; set; }
        public void Prepare()
        {
            Console.WriteLine("Here is a pizza dough base with some tomato sauce spread on it !");
        }
    }
```
 Someone walks up to us and tells us that now we also have to prepare Hawaiian and Pepperoni pizza. One option would be to make separate implementations for them.But we already have a Pizza class, which has a method *Prepare* that outputs pizza in the basic form and also it has data properties which will help us to store the name and price, why not inherit from it (*remember -lesser code*)? But won't the method *Prepare* give us a basic pizza ? Override it ! 

We can override the method *Prepare* to have two different behaviors - one which would give us the Hawaiian pizza and the other which would give us the  Pepperoni pizza. This right here is ***polymorphism*** - The *Prepare* method behaving differently in different contexts.
```javascript
 public class HawaiianPizza : Pizza
    {
        /*the field like name and price need not be written here as we inherit 
          them impiclitly from the parent Pizza class*/
       
       //overridden implementation of Prepare method to give us a hawaiian pizza
    }
```

```javascript
 public class PepperoniPizza : Pizza
    {
       /*the field like name and price need not be written here as we inherit 
          them impiclitly from the parent Pizza class*/
       
       //overridden implementation of Prepare method to give us a Pepperoni  pizza
    }
```

Now that we established what ***polymorphism*** and inheritance is, it is equally important to know how to achieve those. ***Inheritance*** is when a class derives from another class or an interface.The class which other classes *derive* from is called as a ***base class***. Now this ***base class*** can be either an abstract class or a concrete class. Whenever a class is ***incomplete*** with at least one member not implemented then it is called as an ***abstract*** class. For e.g. the class Pizza below
```javascript
 public abstract class Pizza
    {
        public string Name { get; set; }
        public int Price { get; set; }
        public abstract void Prepare();
    }
```
Here you can see that the method Prepare has no body or implementation (don't fret over the keyword abstract in that method, we will come to it soon !) . Given that an abstract class is incomplete , there is no point in creating any instance of it . What if an instance is created and someone calls the Prepare method ? 
Bam ! It would be a disaster since we lack its implementation. And there we have it - ***Abstract classes can never be instantiated*** (the very first point of distinction the search results provide us). Also some search result tell us that "abstract classes" should be defined by the *abstract* keyword. well thank you !

Secondly, a base class could also be a *concrete* class. A concrete class is complete with all its implementations in place- just like a normal class and hence it can be instantiated !

Coming to our abstract and virtual methods. 

By default any method be it of an abstract class or a concrete class cannot be overridden even if the class is inherited by some other class. So if we want a child class to have its own implementation of a particular base class method then we do so by marking the base class method as abstract or virtual -meaning allowing it to be overridden.

Depending on the pizza which we order,say the price would vary , there might be certain discounts on a particular type of pizza, or some logic involved in calculating the price of the pizza. In the base class - Pizza we don't want to handle that , we just want our Pizza class to give us out a pizza base with a tomato sauce layered on it. In this case we will declare a method CalculatePrice as abstract ```public abstract int CalculatePrice();``` .
> Whenever we want the child classes to deal with implementation of a particular method we mark the method as an abstract.

>When doing so, we will only define the signature of the method in the parent class
 
Now the implications of this -
1. Like we established that the abstract classes are incomplete , abstract methods are also incomplete ! ***Abstract methods do not have any default method implementation***.

2. Given this any class inheriting from Pizza **must** override this method ! Obviously it wouldn't make sense to have a method which is just a signature, without any job to do ! (Think about interfaces , how it is required for us to implement them) ***It is mandatory to override abstract methods*** !

3. Also since it is an incomplete method(without any implementation) it is pointless to have it in a concrete class (because concrete classes are complete and we cannot introduce this kind of ambiguity in them !). Hence the reason ***Abstract methods can only be used in an abstract class***.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3d6czxtwqehg6kpyizu6.jpg)

What about virtual methods ?  No matter what, we want to have a basic pizza - a pizza dough base and tomato sauce on it (a l'il bit of cheese doesn't hurt as well!). Here I am sure that under any case I need to have that and not depend on the child classes for the implementation. I will go ahead and mark the method as virtual 
> Whenever we want to have a default behavior or implementation of a method in a parent class we mark this method as virtual

>When we mark it as a virtual method ,in addition to giving a default implementation we also give liberty to the child classes to override it and have their own implementation defined if the default one doesn't meet their needs.


```javascript
 public abstract class Pizza
    {
        public string Name { get; set; }
        public int Price { get; set; }
        public abstract int CalculatePrice();
        public virtual void Prepare()
        {
            Console.WriteLine("Here is a pizza dough base with some tomato sauce spread on it !");
        }
    }
```
Implications
1. Though a default implementation is given in the parent class, the child classes can still have their implementations thus overriding the one given by the parent class.
2. Since a virtual method is complete with a default implementation it is *not mandatory* for the child classes to override it (have their own implementation). ***Virtual methods don't necessarily have to be overridden*** . If you don't override the *Prepare* method in the *Pepperoni* class you are not going to get Pepperoni,You get a basic Pizza !
3. Also since they have a fully functional implementation , ***they can be a part of both abstract and concrete class*** !

Here we have inherited class *PepperoniPizza* from the class *Pizza* .You also see the inherited members of the Pizza class
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fxkzm3hp3l8n9nq7ixud.jpg)

Hope you find this useful.Any suggestions or fixes are always welcome ! :)