C#  

Abstract vs Virtual in C#

If you’ve been developing with C# for a while, chances are you’ve hesitated at least once between making a method abstract or virtual.
Both support polymorphism. Both are overridden in derived classes. Both look similar at first glance.

Let's break down what each keyword really means, why developers confuse them, and how to choose the right one with confidence.

What Does Abstract Really Mean?

An abstract member says:

“This behavior must exist, but I refuse to define it here.”

An abstract method, has no implementation, must be overridden in derived classes, exists only inside an abstract class

public abstract class PaymentProcessor
{
    public abstract void Process(decimal amount);
}

Any class inheriting from this must implement Process:

public class CreditCardPayment : PaymentProcessor
{
    public override void Process(decimal amount)
    {
        Console.WriteLine($"Processing credit card payment: {amount}");
    }
}

If you forget to override it, the compiler stops you.

When to Use abstract

Use abstract classes when:

  • The base class cannot reasonably define behavior

  • Each subclass must decide how it works

What Does virtual Really Mean?

A virtual member says:

“Here’s the default behavior, override it if you need to.”

A virtual method, has a default implementation, may or may not be overridden, allows incremental customization.

public class Logger
{
    public virtual void Log(string message)
    {
        Console.WriteLine(message);
    }
}

Derived classes can override it, but they’re not forced to:

public class FileLogger : Logger
{
    public override void Log(string message)
    {
        File.AppendAllText("log.txt", message);
    }
}

Or they can inherit the default behavior unchanged.

Why Developers Choose the Wrong One

1. “I Might Override This Later”

Developers often use virtual just in case, even when overriding should be mandatory.

This leads to:

  • Incomplete implementations

  • Broken domain rules

If a method must be implemented correctly to function, it should be abstract.

2. Misunderstanding Flexibility

Some believe virtual is “more flexible” than abstract.

In reality:

  • abtract enforces correctness

  • virtual allows optional customization

Flexibility without constraints often leads to fragile systems.

Abstract + Virtual Together?

An abstract class can mix both:

public abstract class Order
{
    public abstract decimal CalculateTotal();

    public virtual bool IsValid()
    {
        return true;
    }
}

In domain-driven design:

  • Abstract expresses business rules

  • Virtual expresses extension points

=> A domain entity with optional overrides is usually a design smell.
=> A framework base class with abstract methods often forces too much rigidity.