Classes in Object Oriented Programming are blueprints for creating objects. While everything in object oriented programming is treated as an object, including classes themselves, each object can have objects inside it that can also act as their own object. Each object has a state and behaviour. State defines the type of object it is, and behaviour defines the operations the object can and can not do. Take a literal object for instance, an apple. An apple is a fruit, and can be eaten, fallen from a tree, or get rotten away. Being a fruit is its state and the actions are its behaviour.
Now, a fruit can also be treated as an object – say a class in object oriented programming. Fruit also has a state (it’s a class) and its behaviour is similar to the apple, and while apple can define really specific things it can do with regards to the actual fruit, the fruit class can have a very broad or abstract definition of its behaviours. Object oriented classes can have inherited classes, which in this case is exactly the apple is. The apple inherits behaviours from fruit. And since the state of the apple is that it is a fruit, and fruit is a class, apple is also a class in definition.
Let’s say that one of the fruits has a behaviour (method in class) to be eaten. While there are different ways a fruit can be eaten, no one can be sure how to eat a fruit without knowing which fruit it is. Hence, it is left literally abstract. Abstract classes have no code within them, they allow the inherited classes to rewrite them. Since we know how to eat an apple, it has actions for its behaviour of being eaten. Abstract classes need to be overridden or the code will not pass, hence abstract classes are defined for the most fundamental of behaviours of a class that have an abstract definition for the class, and a specific definition for the inherited class. In the case of fruit/apple, every fruit needs to have a way of being eaten but no one knows how to eat a “fruit” in general. Although, everyone knows how to eat an apple, this is a perfect place to implement abstract class in fruit (for example beEaten) that the apple and other fruit inherited classes can implement and override to have their own specific way of being eaten.
Fruits in general are healthy to eat and doctors constantly remind us to eat fruits. However, it is not safe to eat some fruits or regulate the quantities they are eaten in. There needs to be a way to make it such that we inform the user which specific fruits are unhealthy to eat. But since most fruits are healthy to eat, you don’t want to include a method in every single inherited class to remind the user that the specific fruit is healthy to eat. No, that would come under code repetition for not so useful reasons. This is where virtual methods come in handy. You can include a virtual method in the fruit class that tells the user the fruit is healthy to eat. Virtual methods do not need to be overridden and will display the default behaviour from the original class until overridden. So, let’s say for an inherited class “poisonous almond” can have an overridden method to tell the user it’s poisonous. All the other inherited classes will display that the fruit is healthy to eat. This makes the job infinitely easier especially when it comes to larger programs.