Interfaces & Abstract Classes

Both define contracts that other classes must fulfill, but they serve different purposes.

Interfaces

An interface defines what a class must do, not how. A class can implement multiple interfaces:

public interface IShape
{
    double Area();
    double Perimeter();
    string Name { get; }
}

public class Circle : IShape
{
    public double Radius { get; set; }
    public string Name => "Circle";

    public Circle(double radius) => Radius = radius;

    public double Area() => Math.PI * Radius * Radius;
    public double Perimeter() => 2 * Math.PI * Radius;
}

public class Rectangle : IShape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public string Name => "Rectangle";

    public Rectangle(double w, double h) { Width = w; Height = h; }

    public double Area() => Width * Height;
    public double Perimeter() => 2 * (Width + Height);
}

Using the Interface

List<IShape> shapes = new()
{
    new Circle(5),
    new Rectangle(4, 6)
};

foreach (IShape shape in shapes)
{
    Console.WriteLine($"{shape.Name}: Area={shape.Area():F2}");
}

Abstract Classes

An abstract class can provide shared implementation along with abstract members:

public abstract class Vehicle
{
    public string Make { get; set; }
    public int Year { get; set; }

    protected Vehicle(string make, int year)
    {
        Make = make;
        Year = year;
    }

    // Must be implemented by subclasses
    public abstract double FuelEfficiency();

    // Shared implementation
    public string Summary()
    {
        return $"{Year} {Make} — {FuelEfficiency():F1} mpg";
    }
}

public class Car : Vehicle
{
    public Car(string make, int year) : base(make, year) { }
    public override double FuelEfficiency() => 30.5;
}

When to Use Which

Feature Interface Abstract Class
Multiple inheritance Yes No
Shared code Default methods (C# 8+) Yes
Fields No Yes
Constructors No Yes

Rule of thumb: Use interfaces to define capabilities (ISerializable, IComparable). Use abstract classes to share code among related classes.