OOP: Interfaces in C#

This post is based on Chapter 9 of Andrew Troelsen’s “Pro C# 2008 and the .Net Platform” available from Apress.

The main purpose of interfaces is to enable us to build types (i.e. classes) that support multiple behaviours. On a more general note they are also at the heart of many OO Design Patterns as they allow you to program to an interface in stead of an implementation – we will return to what that means later on, but just know that if you really want to do OO design, classic inheritance is only the most basic step, and interfaces are a crucial tool for moving on from here.

So, what is an interface? Well an interface defines a behaviour that a class may choose to implement (indeed the java syntax uses “implements” for this, where as C# uses the : also used for inheritance). You can only inherit from one class in the .NET family of languages (see http://en.wikipedia.org/wiki/Multiple_inheritance for some issues around multiple inheritance), but you can implement as many interfaces as you like.

So what is the difference between abstract classes and interfaces, and when should you use what? Well for one thing interfaces have absolutely no implementation – they are simply a description of a behaviour – it’s the implementing class’ job to… implement the actual behaviour, in whatever way it see fit. So I might have two interfaces which defines the following:

	public interface IEnjoyBeer
	{
		void DrinkABeer();
	}

	public interface IActLikeADrunkenLoon
	{
		void DanceOnTheTableInYourPants();
		void ArguePassionatelyWithPeopleAboutThingsYouKnowNothingAbout();
	}

Now we can then define a class that chooses to implement both these – and hence must supply an implementation of all the defined members:

	public class DrunkAsASkunk : IEnjoyBeer, IActLikeADrunkenLoon
	{
		public void DrinkABeer() { Console.WriteLine("Drinking a beer"); }

		public void DanceOnTheTableInYourPants() { Console.WriteLine("Dancing on table in pants!"); }

		public void ArguePassionatelyWithPeopleAboutThingsYouKnowNothingAbout() { Console.WriteLine("Arguing Passionately"); }
	}

In contrast to this, we could do the same with an abstract base class, but we would have to roll both behaviours into one class (no multipl. inherit), which will give you a hint of the limitations of classic inheritance. Note also that we use the virtual method in the base class here to provide a default implementation for drinking a beer:

	public abstract class DrinkLotsOfBeerAndActLikeADrunkenLoon
	{
		public virtual void DrinkABeer() { Console.WriteLine("Drinking a beer"); }
		public abstract void DanceOnTheTableInYourPants();
		public abstract void ArguePassionatelyWithPeopleAboutThingsYouKnowNothingAbout();
	}

	public class DrunkAsSkunk2 : DrinkLotsOfBeerAndActLikeADrunkenLoon
	{
		public override void DanceOnTheTableInYourPants() { Console.WriteLine("Dancing on table in pants!"); }

		public override void ArguePassionatelyWithPeopleAboutThingsYouKnowNothingAbout() { Console.WriteLine("Arguing Passionately"); }
	}

What great examples – no idea how this came to me… Anyways – let’s discuss some aspects of the two examples.

In the last example we have an abstract type that drinks beer and acts like a loon – which doesn’t really ring true, I see an endless number of these types being instantiated across town every weekend, so already we have a hint of a design flaw here. Another good question would be “what about people who enjoy beer without acting like drunken loons?” Or indeed people who act like drunken loons for other reasons than enjoying beer…

In contrast to this, let’s look at the first example using interfaces. So first off the IEnjoyBeer interface makes sense as a separate behaviour – because enjoying beer does not necessarily entail acting like a drunken loon – but, of course for some types it does, but the point is: you have the option to implement either one or both behaviours! You could also have a type that acted like a drunken loon but did not enjoy beer.  Either way – having options is important!

Note also that interfaces are available across class hierarchies – so where inheritance has this fairly rigid tree-like structure, interfaces on the other hand can be plugged in anywhere and at any level.

That is not an exhaustive discussion of interfaces – and we will return to these later when we look at the Strategy pattern in the up and coming OO Design Patterns series – but for now do note that we are not saying that you should use interfaces in stead of inheritance, the two actually compliment each other – we will cover this later, but what you should do is remove variable behaviour from your inheritance structure and instead place this in interfaces. The next step from this will then be moving the implementation of the behaviour (i.e. the interface) out of the specific class, and keep these in reusable classes whose sole purpose is to represent a behaviour. So we will have a more generic interface called IEnjoyADrink – and then a class EnjoyBeer that implements this – and then finally we would design a class called perhaps Person or FridayNightLoon who would implement a IEnjoyADrink implementation of it’s choice – anyways, we’ll return to this… keep reading!

Finally – don’t ever forget to use the Visual Studio Class Diagram tool – this is your new best friend in the world of OOP, just open a new diagram and drop in the types you want to see:

ScreenShot002

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: