Abstract classes - What are they

Well whats this now, something abstract? Honestly it sounds worse than it is. An abstract class is, not unlike the interface, sort of a blueprint of a class. It cannot on itself be instantiated but it serves for other classes to inherit from. Similar to interfaces, the abstract class can have abstract methods which the derived classes shall implement. However unlike the interface, an abstract class may also contain non-abstract methods which are fully implemented and can be used directly from the derived class.

// Abstract class
public abstract class Shape
{
    // Abstract method - to be implemented by derived classes
    public abstract double Area();
    // Regular method with complete implementation
    public void Display()
    {
        Console.WriteLine("This is a shape.");
    }
}

// Derived class inheriting from the abstract class
public class Square : Shape
{
    private double side;

    public Square(double s)
    {
        side = s;
    }

    // Implementing the abstract method from the base abstract class
    public override double Area()
    {
        return side * side;
    }
}

class Program
{
    static void Main()
    {
        // You can't create an instance of the abstract class
        // Shape shape = new Shape(); // This will cause a compilation error

        // But you can create an instance of the derived class
        Square square = new Square(5);
        Console.WriteLine("Area of the square: " + square.Area()); // Output: Area of the square: 25
        square.Display(); // Output: This is a shape.
    }
}

Why bother you might ask

Well the abstract class is fine in that it has both the benefits of the interface, but the functionaly of inheritance..almost. Abtract classes render your code more readable, but also makes it simpler to maintain and scale.

Let me give you an example how I use abstract classes in game development to simplify my workflow on a simplified weapon system.

public abstract class Weapon : MonoBehaviour{
    public float weaponDamage;
    
    public virtual void OnCollisionEnter(Collider col){
        //check if weapon hit an enemy by interface
        if(col.TryGetComponent(out IDamagable damagable){
            damagable.TakeDamage(weaponDamage);
        }
    }
}

public class MeleeWeapon : Weapon{
    //weapons minimum velocity for applying damage
    public float minVelocity = 2.0f;
    public Rigidbody weaponRigidbody;
    
    public override void OnCollisionEnter(Collider col){
        if(weaponrigidbody.velocity.magnitude > minVelocity){
            base.OnCollisionEnter(col);
        }    
    }
} 

public class Arrow : Weapon{
    
}


In this example the abstract Weapon class has implemented the OnCollisionEnter method, the deriving class MeleeWeapon overrides the implementation by introducing velocity of its attached gameobject since this could be relevant for a melee weapon such as a sword. It is perhaps not relevant for an arrow, which in this case simply implements the base class and OnCollisionEnter method.

If you didn’t know about abstract classes before, I hope these examples yielded inspiration as how you could implement it in your own projects. There are a plethora of possiblities where it makes sense to utilize this concept.

Thanks for reading.

/Peter