Fundamentals - Part 7

09/04/2025
2 minute read

Interfaces, Virtual, and Abstract

In this part, we’ll dive into interfaces, virtual methods, and abstract classes. These are fundamental building blocks of object-oriented programming in C#. We’ll explore how they actually work and what it really means when you mark a method as virtual or abstract.


Interfaces

An interface defines a contract — a set of members that a class must implement. When you implement an interface, the compiler generates metadata so that at runtime, your object can be treated as that interface type.


public interface ILogger
{
    void Log(string message);
}


public class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine($"[LOG] {message}");
    }
}

Usage:

ILogger logger = new ConsoleLogger();
logger.Log("Hello World!");

What happens behind the scenes? At runtime, the CLR maintains a vtable (virtual method table) that maps the interface method to the concrete implementation (ConsoleLogger.Log). That’s why you can call Log on an ILogger reference, even though the runtime object is ConsoleLogger.


Virtual Methods

A virtual method allows derived classes to override the implementation. When you call a virtual method, the runtime looks it up in the vtable (virtual method table) to see if the object provides an override.


public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some generic animal sound...");
    }
}


public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

Usage:


Animal a1 = new Animal();
Animal a2 = new Dog();

a1.Speak(); // Some generic animal sound... a2.Speak(); // Woof!


Abstract Classes

An abstract class is a class that cannot be instantiated. It can include both abstract methods (which must be implemented by subclasses) and normal or virtual methods.


public abstract class Shape
{
    public abstract double Area(); // no implementation
    public virtual void Describe()
    {
        Console.WriteLine("I am a shape.");
    }
}


public class Circle : Shape
{
    public double Radius { get; set; }
    public Circle(double radius) => Radius = radius;
    public override double Area() => Math.PI * Radius * Radius;
    public override void Describe()
    {
        Console.WriteLine($"I am a circle with radius {Radius}.");
    }
}

Usage:

Shape s = new Circle(5);
Console.WriteLine(s.Area());   // 78.54
s.Describe();                  // I am a circle with radius 5.

What’s happening under the hood? The CLR enforces that abstract methods must be overridden in derived classes. The runtime again uses vtable dispatch for virtual/abstract calls, so the correct implementation is resolved dynamically.

Final Thoughts

  • Interfaces define contracts. Classes promise to implement them.
  • Virtual methods allow derived classes to override behavior.
  • Abstract classes enforce implementation while also providing shared logic.⠀

All of these rely on the same mechanism: method tables (vtable dispatch), which the CLR uses to resolve calls at runtime.

An error has occurred. This application may no longer respond until reloaded. Reload x