72

"Abstract class" and "interface" are similar concepts, with interface being the more abstract of the two. One differentiating factor is that abstract classes provide method implementations for derived classes when needed. In C#, however, this differentiating factor has been reduced by the recent introduction of extension methods, which enable implementations to be provided for interface methods. Another differentiating factor is that a class can inherit only one abstract class (i.e., there is no multiple inheritance), but it can implement multiple interfaces. This makes interfaces less restrictive and more flexible. So, in C#, when should we use abstract classes instead of interfaces with extension methods?

A notable example of the interface + extension method model is LINQ, where query functionality is provided for any type that implements IEnumerable via a multitude of extension methods.

essential
  • 105
Gulshan
  • 9,532

7 Answers7

63

When you need a part of the class to be implemented. The best example I've used is the template method pattern.

public abstract class SomethingDoer
{
    public void Do()
    {
        this.DoThis();
        this.DoThat();
    }

    protected abstract void DoThis();
    protected abstract void DoThat();
}

Thus, you can define the steps that will be taken when Do() is called, without knowing the specifics of how they will be implemented. Deriving classes must implement the abstract methods, but not the Do() method.

Extensions methods don't necessarily satisfy the "must be a part of the class" part of the equation. Additionally, iirc, extension methods cannot (appear to) be anything but public in scope.

edit

The question is more interesting than I had originally given credit for. Upon further examination, Jon Skeet answered a question like this on SO in favour of using interfaces + extension methods. Also, a potential downside is using reflection against an object hierarchy designed in this way.

Personally, I am having trouble seeing the benefit of altering a currently common practice, but also see few to no downsides in doing it.

It should be noted that it is possible to program this way in many languages via Utility classes. Extensions just provide the syntactic sugar to make the methods look like they belong to the class.

Steven Evers
  • 28,180
26

It's all about what you want to model:

Abstract classes work by inheritance. Being just special base classes, they model some is-a-relationship.

For example, a dog is an animal, thus we have

class Dog : Animal { ... }

As it doesn't make sense to actually create a generic all-animal (what would it look like?), we make this Animal base class abstract - but it's still a base class. And the Dog class doesn't make sense without being an Animal.

Interfaces on the other hand are a different story. They don't use inheritance but provide polymorphism (which can be implemented with inheritance too). They don't model an is-a relationship, but more of a it does support.

Take e.g. IComparable - an object that supports being compared with another one.

The functionality of a class does not depend on the interfaces it implements, the interface just provides a generic way of accessing the functionality. We could still Dispose of a Graphics or a FileStream without having them implement IDisposable. The interface just relates the methods together.

In principle, one could add and remove interfaces just like extensions without changing the behaviour of a class, just enriching the access to it. You cannot though take away a base class as the object would become meaningless!

Dario
  • 1,608
  • 10
  • 13
4

I just realized, that I haven't used abstract classes (at least not created) in years.

Abstract class is a somewhat strange beast between interface and implementation. There is something in abstract classes which tingles my spider-sense. I would argue, one should not "expose" the implementation behind interface in any way (or make any tie-ins).

Even if there is a need for common behavior between classes implementing an interface, I would use an independent helper class, rather than an abstract class.

I would go for interfaces.

Maglob
  • 3,849
2

IMHO, I think that there is a mixing of concepts here.

Classes use a certain kind of inheritance, while interfaces use a different kind of inheritance.

Both kinds of inheritance are important and useful, and each one has its pros and cons.

Let's start at the beginning.

The story with interfaces starts a long while back with C++. In the mid-1980s, when C++ was developed, the idea of interfaces as a different kind of type was not yet realized (it would come in time).

C++ only had one kind of inheritance, the kind of inheritance used by classes, called implementation inheritance.

To be able to apply the GoF Book recommendation: "To program for the interface, and not for the implementation", C++ supported abstract classes and multiple implementation inheritance to be able to do what interfaces in C# are capable (and useful!) of doing.

C# introduces a new kind of type, interfaces, and a new kind of inheritance, interface inheritance, to offer at least two different ways to support "To program for the interface, and not for the implementation", with one important caveat: C# only supports multiple inheritance with interface inheritance (and not with implementation inheritance).

So, the architectural reasons behind interfaces in C# is the GoF recommendation.

I hope this can be of help.

Kind regards, Gastón

1

Applying extension methods to an interface is useful for applying common behaviour across classes that may share only a common interface. Such classes may already exist and be closed to extensions via other means.

For new designs I would favour the use of extension methods on interfaces. For a hierarchy of Types, extension methods provide a means to extend behaviour without having to open the entire hierarchy for modification.

However, extension methods are unable to access private implementation, so at the top of a hierarchy, if I need to encapsulate private implementation behind a public interface then an abstract class would be the only way.

Ed James
  • 1,331
  • 1
  • 10
  • 14
0

I think that in C# multiple inheritance is not supported and that's why concept of interface is introduced in C#.

In case of abstract classes, multiple inheritance is not supported either. So it is easy to decide on wether to use abstract classes or interfaces.

-1

I'm in the process of implementing an Abstract class in my project simply because C# does not support operators (implicit conversions, in my case) on Interfaces.

palswim
  • 99