My musings about .NET and what not

Interfaces vs. Abstract Base Classes

This is something I’ve gone back and forth on for a while now. Having faced this decision once again in my latest project, I figured it was time to solidify my thoughts on it. Here’s my take on the seemingly endless Interface vs. Abstract Base Class debate.

As we know, a well-structured application favors loose coupling to reduce dependency among classes and to make the resulting system less rigid, and more resilient to change. One of the ways we do that, as originally proposed by the GoF, is this:

Program to an interface, not an implementation.

Here, they are speaking of an “interface” in a general sense; that is, a construct that provides a specification for a type without implementing its members. When a class implements the interface, it is forced to implement each of the members defined in it. This serves as a “contract” to whatever object consumes an instance of the implementing class -- in effect, it warrantees that the members defined by the interface will be available.

Therefore, if a member in class A consumes an instance of class B, where B is an implementation of interface N, you can rewrite A to consume N instead. A never needs to be aware of B’s actual type, as long as B fulfills the contract defined by N. In fact, A can (and should) remain totally unaware of the existence of B. This lets you alter B’s implementation of N without breaking A, and provide new implementations of N (C, D, E and so on), all of which can be readily consumed by A without alteration. That’s loose coupling in action.

In .NET languages, there are two constructs available for accomplishing this: using an abstract class, or an actual interface construct. Both require the classes that inherit it (in the case of an abstract class) or implement it (in the case of an interface) to provide implementations for any abstract members. Hence the debate: which is better? Are there situations in which it makes sense to opt for one over the other?

I happen to be currently reading Dino Esposito’s latest book, Microsoft .NET: Architecting Applications for the Enterprise, in which he offers the following opinion:

Should you use an interface? Or should you perhaps opt for an abstract base class? In object-oriented languages that do not support multiple inheritance – such as Java, C#, or Visual Basic .NET – an interface is always preferable because it leaves room for another base class of your choice.

As great as this book has been so far (I’m about halfway through), I sort of feel a little uneasy about this “interface is always preferable” argument. While it’s true that an interface may be more flexible in that it allows for the possibility of inheriting from another base class, I think this argument holds a lot less water in the case where the interface is meant to define a type’s core functionality.

In other words: I wonder if it doesn't make more sense, at least from a semantic point of view, to use an abstract base class if the types that will inherit from it share common core functionality. If the types merely share a common ability or characteristic, yet are otherwise functionally unrelated, then use an interface.

Or, to put it in even simpler terms: as a general rule, if it can be said that an object of type B is a kind of A, then class B should inherit from the abstract class A. On the other hand, if A is only a characteristic of or an ability of an object of type B, then class B should implement the interface A.

Let’s take a typical example from the .NET Framework BCL, like SqlConnection.

public sealed class SqlConnection : DbConnection, ICloneable

You see that this class inherits from DbConnection, which is an abstract class. DbConnection defines members which are common to all types of connections. This abstract class is in turn inherited by OdbcConnection, OleDbConnection, and OracleConnection, as well as SqlConnection. These represent specific types of connections, which all share a common functionality in that they are all used to connect to a database.

You’ll also notice that SqlConnection implements the ICloneable interface, because it needs to support cloning beyond that supplied by MemberwiseClone (which all .NET objects already inherit). However, the need for an object to be able to deep-copy itself is not a requirement exclusive to connections. It is, in fact, a necessary feature for many other types, most of which are totally unrelated to connections. For example, System.Xml.XmlNode, System.Array, and  System.Web.UI.WebControls.Parameter all require the ability to clone, and thus each of them implements the same ICloneable interface.

You could restate it this way: A SqlConnection object is a kind of DbConnection, and cloning is an ability of a SqlConnection object. (You could also say that clonability is a characteristic of a SqlConnection object.) Therefore, SqlConnection inherits the abstract class DbConnection, and implements the interface ICloneable.

If nothing else, this should indicate to you why it’s no accident so many of the .NET interfaces end with the suffix “-able”.

Now, I realize the distinction I’m drawing here may not be that important in many cases. Of course, the real point is how separating specification from implementation lets us “program to the interface” – that is, to write code that’s designed to work with a base class (or interface, as the case may be), and to be able to use that code with instances of any class derived from the base class. This lets us leverage the benefits of polymorphism to create more robust code.

So anyway, that’s pretty much when I’m standing on the Interface vs. Abstract Base Class issue. At least for the rest of this week. ;-)

Subscribe to this blog for more cool content like this!

kick it on DotNetKicks.com

shout it on DotNetShoutOut.com

vote it on WebDevVote.com

Bookmark / Share

    » Similar Posts

    1. Singletons vs. Static Classes
    2. Should We Return Null From Our Methods?
    3. Defensive Programming, or Why Exception Handling Is Like Car Insurance

    » Trackbacks & Pingbacks

    1. You've been kicked (a good thing) - Trackback from DotNetKicks.com

      Interfaces vs. Abstract Base Classes — April 16, 2009 12:34 AM
    2. Thank you for submitting this cool story - Trackback from DotNetShoutout

      Interfaces vs. Abstract Base Classes — April 16, 2009 2:07 PM
    3. Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #329

      Reflective Perspective - Chris Alcock » The Morning Brew #329 — April 17, 2009 2:31 AM
    4. 9efish.感谢你的文章 - Trackback from 9eFish

      Interfaces vs. Abstract Base Classes : LeeDumond.com — April 17, 2009 9:47 AM
    5. Pingback from Yet another debate on Interfaces vs. Abstract Base Classes | Xelluloid

      Yet another debate on Interfaces vs. Abstract Base Classes | Xelluloid — April 19, 2009 4:32 PM
    6. Pingback from Noch eine Debatte ??ber Interfaces vs. Abstrakte Klassen | Xelluloid

      Noch eine Debatte ??ber Interfaces vs. Abstrakte Klassen | Xelluloid — April 19, 2009 8:34 PM
    7. My last "versus" post seemed to elicit a good number of interesting responses. Today, I'm musing about Singletons vs. Static Classes -- two constructs which appear to accomplish the same task. Or do they?

      Singletons vs. Static Classes — April 27, 2009 2:27 PM
    Trackback link for this post:
    http://leedumond.com/trackback.ashx?id=50

    » Comments

    1. Cohen avatar

      I have to say I don't agree with you on this one. Not using an Interface can (and will probably bite you). I've seen a lot of people on blogs complain they had to inherit some base class instead of an interface and where stuck with it's implementation.

      For instance it's a lot harder (and less flexible) to mock an abstract class than an interface.

      So I personally go by: use always the interface and if you have a common implementation you can combine it with an abstract class, but don't use the abstract class to attain polymorphism. Unless you specifically want to force the inheriting classes to have a common implementation which is unchangable (which are not defined as virtual).

      Cohen — April 16, 2009 8:03 AM
    2. Owen avatar

      I agree with Cohen, but interfaces have problems as well. In particular, it is very difficult to version an interface. Once an interface goes public, you can't add a method to it without breaking existing code; with a base class you could add a non-abstract method or overloads. Extension methods do seem to address this, but it's something to consider. (It's why COM is littered with interfaces like Foo, Foo2, Foo3...)

      Owen — April 16, 2009 2:15 PM
    3. Lee Dumond avatar

      @Cohen - Tools like TypeMock don't require interfaces like RhinoMocks does. I understand TypeMock isn't free, but doesn't it make more sense to find/use tools that complement your chosen architecture, rather than architecting a solution around the capabilities of your tools?

      @Owen - Doesn't what you're saying actually support my point? If you use interfaces with types that don't share a common implementation, they are likely to remain simpler and you won't have to "break the contract" if and when you need to enhance a type's core functionality.

      Lee Dumond — April 16, 2009 2:48 PM
    4. Martin Evans avatar

      There's no right answer to this question apart from whats going to be the best fit for the problem domain.

      How many objects in your domain can you see inheriting an abstract class?

      If the inheriting objects are simply going to overide methods in the base, you might as well go down the interface route.

      For what it's worth, the last time I went down the base class route, I ran into testability headaches.

      Hope this helps... and let us all know how the book ends!

      Martin Evans — April 16, 2009 3:49 PM
    5. bob avatar

      The interface argument has become overblown in enterprise systems. There are only 2 places an interface really belongs.

      Interaction between different systems, and interactions between subsystems.

      You could make an API argument, but that would suggest that different subsystem implementations would potentially be behind the API in which case its a subsystem.

      "Loose coupling" has been twisted to mean a lot. And interfaces were supposed to solve it. They haven't.

      Ive seen systems that inherit interfaces 25 layers deep on all kinds of classes. Try reimplementing any of them if not all of them. Its a joke.

      bob — April 16, 2009 9:01 PM
    6. xxjthxx avatar

      You're right. But the real problem, I think, and I believe C# handles it very poorly is when there's a common behaviour AND implmentation for group of objects which are not related by inheritance. In this case you usually end up writing redundant code (for example by implmenting the same interface with some common helper class).

      xxjthxx — April 17, 2009 9:32 AM
    7. dennis avatar

      There are a lot of good arguments here. I think the bottom line has to be to use an interface when you need an interface and use an abstract class when that makes more sense.

      Coming from Java programming I must say that I missing not being able to implement constants and such in C# as part of an interface, for example, when they are only used for return types on the interface members.

      dennis — April 18, 2009 12:04 PM
    8. Matthieu DUFOURNEAUD-RAVEL avatar

      I think the extension methods can be used to build the base methods of an interface, here is a basic example:

      public interface ITest1

      {

      int DoSomething(int a, int b);

      }

      public static class ITest1Extensions

      {

      public static int DoSomethingBase(this ITest1 test1, int a, int b)

      {

      return a + b;

      }

      }

      public class Test1 : ITest1

      {

      public int DoSomething(int a, int b)

      {

      return this.DoSomethingBase(a, b);

      }

      }

      Does anybody already try this pattern ?

      Matthieu DUFOURNEAUD-RAVEL — April 21, 2009 3:44 AM

    » Leave a Comment