Making a class abstract allows you to use abstract functions. Abstract functions allow you to guarantee that children/subclasses will have these functions on them. The abstract class will not be instantiatable (can't exist "in the world").
Example:
public abstract class Dog
cannot exist via
Dog dog = new Dog()
but a subclass
public class GreatDane : Dog
can exist in the world.
GreatDane greatDane = new GreatDane()
Why? It makes no sense to create a generic "dog" in the world. Being abstract stops it being created. It also allows you to have abstract function template/stubs that all children/subclasses must have.
public abstract class Dog
{
public abstract void Bark();
}
public class GreatDane : Dog
{
public override void Bark()
{
}
}
Why not use an Interface like IBarkable?
You could, but having the base class "Dog" allows for shared/common behaviour. You could have regular functions, virtual functions or abstract functions.
For example, if 90% of dogs bark the same way, you can make Bark() virtual, so there is default/shared/common implementation.
public abstract class Dog
{
public virtual void Bark()
{
}
public void WagTail()
{
}
}
public class GreatDane : Dog
{
}
public class Rottweiler : Dog
{
public override void Bark()
{
}
}
With interfaces, every Bark() would be unique, leading to copy & pasted code.