Abstract Class VS Interface in C#

You can open any C# tutorial and you’ll find some information about abstract classes and interfaces. Most likely, you’ll not find any information about what is the difference between abstract class and interface.
This theme was discussed earlier on the Internet several times but I want to consolidate all the most important thoughts regarding the problem of choosing between an abstract class and interface in this post.

Let’s consider the mechanical and semantic difference between abstract classes and interfaces.
What is an abstract class and what is an interface? The main mechanical difference is that an abstract class can have a default implementation, whereas an interface is just a bunch of member declarations, it defines their signatures. Here is a short example:

public abstract class AlgorithmBase {
    public int Do() {
        int a1 = Operation1();
        int a2 = Operation2();
        return a1 + a2;
    }

    public virtual int Operation1() {
        return 55 ^ 35;
    }

    public virtual int Operation2() {
        return 21 + 48;
    }
}

public interface Algorithm {
    int Operation1();
    int Operation2();
}

Also, you can’t create an instance of an abstract class. So, the mechanical difference is pretty obvious for any meaningful C# developer. Let’s talk about the semantic payload of abstract classes and interfaces.
Very often you can hear that interfaces define contracts. This statement becomes more convincing with the fact that in WCF we treat interfaces and contracts equally. In WCF, a service contract can only be represented by an interface.
In the real world, including the real world outside of programming, contracts have some semantic payload. Usually, they determine some kind of relationships between people, rights, objects and so on. Interfaces have no any semantic payload. They determine nothing except signatures. But signatures don’t bear any significant semantic payload. An interface represents just a shape. Thus, interfaces are not contracts. Here is an example of a contract provided by Krzysztof Cwalina:

public abstract class CollectionContract<T> : IList<T> {
    public void Add(T item) {
        AddCore(item);
        count++;
    }

    public int Count {
        get { return count; }
    }

    protected abstract void AddCore(T item);

    private int count;  
    ...
}

This contract says that when an item is added to the collection, the Count property is incremented by one. In addition, this contract is locked for all subtypes.
Interfaces are made of stone. They can’t be easily changed without breaking existing clients. At the same time, interfaces are easily extendable by clients. A client can extend an interface by extension methods and by the way, if a client wants to implement an interface on a class which already inherits from another class, a client can easily do that, a client couldn’t do that with an abstract class instead of an interface, since multiple inheritance in C# is deprecated.

So, in the end, an interface is more supple from the client’s perspective: any class can implement as many interfaces as it wants to. Unfortunately, an interface is more rigid from the developer’s perspective: it can’t be easily changed and it does not support any kind of reusability.
An abstract class is supple from the developer’s perspective: it supports reusability, it supports encapsulation, it can be extended easily without breaking existing clients.
With all that said, we can conclude the interesting rule of thumb: use abstract classes for building internal APIs and use interfaces for providing external points of extension. Remember, this is not a dogma, this is a rule of thumb.

Look at an example from an open-source project.

public abstract class BitMatrix {
    public abstract bool this[int i, int j] { get; set; }
    public abstract int Width { get; }
    public abstract int Height { get; }

    internal MatrixSize Size {
        get { return new MatrixSize(Width, Height); }
    }

    internal bool this[MatrixPoint point] {
        get { return this[point.X, point.Y]; }
        set { this[point.X, point.Y] = value; }
    }

    internal void CopyTo(SimpleBitMatrix target, MatrixRectangle sourceArea, MatrixPoint targetPoint) {
        for (int j = 0; j < sourceArea.Size.Height; j++) {
            for (int i = 0; i < sourceArea.Size.Width; i++) {
                bool value = this[sourceArea.Location.X + i, sourceArea.Location.Y + j];
                target[targetPoint.X + i, targetPoint.Y + j] = value;
            }
        }
    }

    internal void CopyTo(SimpleBitMatrix target, MatrixPoint targetPoint) {
        CopyTo(target, new MatrixRectangle(new MatrixPoint(0, 0), new MatrixSize(Width, Height)), targetPoint);
    }
}

public abstract class SquareBitMatrix : BitMatrix {
    private readonly int m_Width;

    protected SquareBitMatrix(int width) {
        m_Width = width;
    }

    internal static int GetWidthByVersion(int version) {
        return 17 + 4 * version;
    }

    public override int Height {
        get { return Width; }
    }

    public override int Width {
        get { return m_Width; }
    }
}

The BitMatrix is an abstract class which exposes a lot (not so much in fact, but considerable amount) of reusable code. The SquareBitMatrix overrides the Width and Height and reuses the base class logic.
I’ll not provide code examples of interfaces from BCL, just recall that BCL provides ICollection, IList, INotifyPropertyChanged and tons of other interfaces. This is done so because the extensibility from the client’s perspective is more important in these cases.

This will be a series of articles directly connected with my new course on the subject of “Designing and Implementing API in C#”. Look into that article about my new course and join my mailing list in order to get maximum possible discounts on my programming video courses.

  • Sasidhar Vasam

    Nice article. I would to add one line when we have to design abstract classes or interfaces

    whenever we are designing set of functionally related classes go for abstract classes to define abstract and concrete members.

    whenever we are designing non funtional classes go for interfaces

  • Alexander Lvovich

    Good reading. The decision whether to use abstract class or interface lays in fact that in .net class can be derived for ONLY one class but can implement many interfaces.
    Also existence or need of basic logic can enhance reasoning for abstract class usage

  • Imraaz

    Good article. Adding more to the discussion, the abstract class with sub-classes (inheritance) is mostly used for objects with “is a” relationship E.g A BMW is a type of Car, where Car will be your base class and BMW is a type of car which can inherit base methods and properties . Whereas Interfaces normally have “has a” relationship E.g. A Car has an Engine, a truck has an Engine and list goes on. So the engine will pretty much act as an interface which can be implemented to Cars and trucks. And Off course these objects will have different implementation of the Engine method.

    Please do comment if I have missed anything. I am still a newbie with these concepts.