Click here to Skip to main content
15,886,258 members
Articles / Programming Languages / C#

Interfaces In Action

Rate me:
Please Sign up or sign in to vote.
4.48/5 (40 votes)
22 Apr 2012CPOL9 min read 58.1K   573   87   22
A basic introduction to interfaces and their usage in development

Introduction

Just recently, I weighed in on a post where the author was making a legitimate complaint about the quality of articles submitted. I won't go into the details, but since that discussion I've been tempted to write my first article as I think I should try my best and contribute more to the community. Today I commented on another authors post, it was well written and I could follow the thread of the article, but the examples were a little too obscure (for my liking), so their real world application might not be immediately apparent to the reader. So, on to my first article.

It took me a while to grasp the concept of interfaces. It's not that they're particularly difficult as a concept, but how and where to apply them is where a developer can struggle. My intent with this article is not to show anything radically different, not to try and say "my article better describes x" but to try and put my understanding of interfaces and their practical implementation into my words, so that the reader has a different perspective with which to view the topic.

Assumptions

I'm going to make the assumption that you understand (not necessarily are a master of) basic object orientated principals and that you are comfortable with the following words.

  • object
  • class
  • property
  • method

What is an Interface

The simplest analogy I can draw for an interface is that of a contract. A landlord of a property might have a standard contract, everybody expecting to live in a property owned by that landlord agrees that they will adhere to the rules and guidelines contained within it. How two tenants keep within that rule set is entirely up to them, but they are both bound by the same contract. An interface is a guarantee that certain behaviors and values will be available to anybody using an object that implements that interface.

Declaration

You define an interface in C# as follows:

C#
public interface ICustomAction<T>
{
     string Name { get;}
     string Description { get; set; }
     T Execute( T val );
}

An interface is always public. You cannot define access modifiers on the properties and methods defined within and you cannot provide any implementation for your interface.

Note: If you are familiar with C# 3.0's features, specifically auto-properties, do not confuse your interface definition with an auto-property. It is not implementation in the case of an interface.

Use

You cannot create an object of an interface, you can only create an object of a class that implements an interface. Although you will see examples such as:

C#
public void MyMethod( ICustomAction<int> action)
{
}

You can never actually declare an object of type ICustomAction. Give it a go, see what happens.

C#
ICustomAction<int> action = new ICustomAction<int>( );

Instead, you need to define a class and implement the interface, defining the functionality that you have agreed an object implementing this interface will provide.

C#
public class UpdateOrderAction : ICustomAction<int>
{
    public string Name
    {
        get
        {
          return "UpdateOrderAction";
        }
    }

    public string Description {get;set;}

    public int Execute( int val )
    {
       //
    }
}

Not very useful at the moment. However, you've actually created a class from which you can instantiate an object and you will guarantee it provides a name and a method 'Execute'. Notice that we are now able to define access modifiers on the properties and methods defined. You are however, limited to your properties and methods being made public.

Why Only Public?

As I said earlier, when you define an interface, you are making a guarantee that any properties and methods defined on that interface are available on all classes that implement it. Let us say that Jeff and Bill are writing a system together. Bill is going to work on the back end accounting system, Jeff is going to be working on the front end, data entry system. They're starting their development at the same time, so there is no existing code to work from. Jeff will be allowing data entry clerks to create invoices for customers, Bill's back end system will be responsible for posting those invoices to ledgers etc. So, Bill and Jeff sit down and flesh out the rough design of their system, what they'll need from one another. They agree that an invoice should contain:

  • Id
  • CustomerReferenceNumber
  • Value

So, they define an interface:

C#
public interface IInvoice
{
    int Id {get;set;}
    int CustomerReferenceNumber {get;set;}
    decimal Value {get;set;}
}

Now, they both go away happy. Bill knows that he can work with an IInvoice object coming from Jeffs front end, Jeff knows that when he is ready, he can produce an invoice object that implements the IInvoice object they just discussed and he won't hold Bill up. Now, if Jeff decided that when a customer was a high profile customer, he would make the customer reference number private on the invoice, he would not be fulfilling the contract that he and Bill had agreed upon and that the IInvoice interface had promised. So, any class implementing an interface must make all the properties and methods that make up that interface public to all.

Back to the Point

Using the example of the ICustomAction interface from earlier, we'll now continue to try and expand upon implementing our interface in a class. We defined the custom action interface as being of a type, so when we implement the interface in our object, in this case:

C#
public class MultiplyAction : ICustomAction<int>
{
     public string Name
     {
           get
           {
               return "Multiply Action";
           }
     }

     public string Description { get; set; }
     public int Execute( int val )
     {
           Console.WriteLine( "Name: {0} Value: {1}", Name, val );
           return val * 2;
     }
}
  • MultiplyAction - The name of the class into which we put the behavior(implementation) of our interface.
  • ICustomAction<int> - This class will implement the ICustomAction interface and will accept integer types wherever T was specified in our interface declaration.
  • public int Execute( int val) - In the interface, this looked like T Execute( T val). We're now implementing it, so it's time for a solid type.

To see this in work, take a look at the sample source code. The generics I used are a little beyond the scope of this article, but hopefully my example code makes them understandable enough. You could define your ICustomAction like so:

C#
public interface ICustomAction
{
    string Name {get;}
    string Description {get;set;}
    int Execute( int val);
}

A Brief Summary

In the attached code, there are three custom actions. One is the manager class that has a list of custom actions attached to it, the others are the actions that we can perform. In the program.cs, I create an object of type ActionManager and I add two custom actions to it. Notice that the code only specifies that an ICustomAction<int> is required, not that a Multiply or DivideAction is required.

When Interfaces Come into their Own

Without trying to throw around a bunch of common phrases (such as dependency injection, loose coupling, etc., few of which I believe I have a strong grasp of) Programming to the interface, rather than a solid implementation of an object gives the developers the flexibility to swap out the actual implementation without worrying too much about how the program will take the new change. Back to Jeff and Bill from before. Now, let us say that Jeff and Bill didn't have their original discussion, let us say that the conversation went something like:

Jeff: Hey Bill, so what do you need from my data entry system?

Bill: Well Jeff, I need to get an invoice, I need an Id, a customer reference number and a value. I can just tie up the customer reference number to the account and then post a value on the ledger.

Jeff: Oh great! I'll pass you an invoice just like that.

So, they go away and a week later, Jeff posts an Invoice object to Bill. Great. The system is working fine and they have got it up and running in record time. Their managers are overjoyed, the business is efficient. A month later, Jeff's manager approaches him.

Manager: Jeff, we have a bit of an issue. We're having trouble reporting on the invoices. Some of our customers have the ability to override on an invoice by invoice basis just what terms they have.

Jeff: Hmmmm

Manager: You'll sort it out, that's great!

So, Jeff goes away and thinks long and hard about this. He decides that the best way of doing this is to create a new type of invoice, a SuperInvoice (don't name your objects super anything!). He gets it done in an hour and then implements the change on the system. *BANG*

Bill: Jeff, what happened? The ledger postings crashed, it's talking about an invalid cast.

Jeff: Ooops, we should have talked about interfaces in the first place.

When Jeff implemented the change, he didn't think that Bill was dependent upon an Invoice object. When he implemented SuperInvoice, he just created a new type and implemented it within the system. There are several solutions to this problem, those of you familiar with inheritance may see my example as poor as Jeff could have just inherited from Invoice and all should have been fine. However, what Bill and Jeff originally did do was create an IInvoice interface. It gave Bill and Jeff the ability to program their respective parts without worry of the actual implementation of each object, when Jeff came to implement SuperInvoice, he would have implemented the interface and the system at Bill's end would have been none the wiser. It didn't need to be any the wiser. As far as Bill is concerned, it is an invoice, he doesn't need to worry about whether it carries anything not relevant to his system.

Summary

Interfaces are used everywhere throughout the .NET Framework and they are a powerful tool in object orientated programming and design. You may have seen IEnumerable, IDisposable and several others quite frequently while developing other programs. In the case of IDisposable, implementing this interface guarantees you will have a Dispose method on your object (whether you do anything or not[bad practice]).You may see:

C#
using( SqlConnection connection = new SqlConnection( ))
  {
  //Code
  }

The using keyword will take any object that implements IDisposable. When the using statement is complete, it implicitly calls Dispose. If you define your methods to return an IEnumerable<string> it means you can return any collection that implements the IEnumerable interface and contains strings. You can return a list or any other firm object but you guarantee that the object you return will definitely provide certain properties and methods.

In Closing

Well, that is the end of my first article. Hopefully some found it useful and informative. I do now realise the effort that goes into producing something like this and even though I work day in, day out as a developer I realise just how difficult it is to produce a "real world" example to work with. And I apologise for my criticism of other efforts.

History

  • v1.00 - Jan 27th '10 - First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I'm originally from the UK, I hail from Saddleworth (near Manchester). I moved to the US in 2007 and live with my wife and daughter in New Jersey.

I started late into software development and do as much learning as I can. I've been a developer for 10 years, starting with Business BASIC on DG/UX boxes, moving to do Windows Mobile development using .NET CF. My tool of choice is C#, however I'll pick at whatever language is good for the job.

I struggle to concentrate on one thing, so don't really learn a topic very well before moving on to the next. It's my aim to sort this out and learn more about C#, the language, the design and more importantly how to use it like the masters I see on this site.

Comments and Discussions

 
GeneralA bit practical look on interfaces Pin
Member 882354322-Apr-12 15:14
Member 882354322-Apr-12 15:14 
I appreciate the article and your work to take time to write it down. It is certainly not easy to write an article, especially about subject you are not overy comfortable with. But I feel that you better might have wait untill you understand principles behind interfaces more thorough. I am not having any claims that I can do it better, or that you don't know what you are talking about; but you are yourself saying several times (in article and comments) that you don't understand certain aspects. In that case it is maybe better to wait until subject mature. I hope you don't take ill my criticism, I don't mean to be rude.

I have red your article and I agree with everything you say; it is all OK. However it is bit shallow and just takes up the standard explanation of how to use interfaces. You will find that contract analogy in any text book or article about OOP programming, and pretty much every course book out there will bring up exactly same analogy.

I don't say it is wrong, because the contract analogy is easy to grasp and gives good starting point to use interfaces, but it is not the whole story.

It might be more illustrative, and thus help understanding to go through different implementations of interface concept by differnt parts of the language, and by different programming languages. Haskell for example, has great use of interfaces, while it does not even include interface keyword. Also trying to actually understand what interface are supposed to solve is also very illustrative and might help to get the concept.

I will not (and cannot) attempt to explain all I believe should be explained about interface paradigm (because it really is a paradigm, not just a language feature) but I will try to give few illustrations for my claims.

I see interface just as a practical answer to a natural need in programming. Maybe I should also say it's a tool to help you with solving certain problems that arise in programming. It is very simple concept; really; there is no need to give it special treatman; but I understand that it might feel very abstract after reading a wrong article or programming book.

I agree that term contract programming, and contract analogy to interfaces are well-describing what interfaces are, but also think it is a little unfortunate choice of analogy. Term contract, and that analogy about landlord makes it sound like an interface is something we are forcing on us.

I also remember discussions when I was a student and natural comments and reactions students had about interfaces. We used Java at university; our course book was OOP and Modelling with Java by David Barnes. Java was not first language to use interfaces as a concept, or even keyword, but was probably the language that made interface programming popular and common-accepted; and the one from where C# implementation stems from. Some students where wondering why should they use interfaces? Anyway interfaces have only signatures; and one has to implement all methods in all classes. Many people agreed it is usefull, but they also thought it was just a ill-done fix to java language for the lack of multiple inheritance. I remember that even our teacher said that it is Javas way to implement multiple inheritance. But it is not!

One should not start learning interfaces from that end-point where we started (D. Barnes used very same analogy of contract, and obligation of a programmer to implement that interface). To make things even worse, most of material where we were supposed to get interface concept learned and understood where in context of GUI programming. In Java it usually involves implementing mouse and key interfaces and window adapters and alike. With few exceptions of comparator and comparable. First why I think it is bad to use event classes to illustrate interface use? Because (at least in Java) you write a lot of repetitive code which is pretty similar in most places, and one just get bored with it, and thus take whole concept with negative attitude.

Second why is it bad with contract analogy? Because the contract is (for the most people) something that is imposed on one; something that is not really ones will, but something one have to accept and adapt to in order to become eligible for certan service or product. As such it does not sounds really nice. And I said it was even worse in combination with javas event interfaces, is because, when you have to write 5 empty methods just to get to one you are really interested in, you kind-a FEEL as it is imposed on you. For a student, just learning and getting all that stuff, it feels kind-a brain dead. why not just allowing multiple inheritance and find some clever way to solve that dreaded diamond-problem?

For me it was clear that technique was usefull and I liked it, but I admit I was also a bit annoyed at first. My liking come first when I took compiler course and realized how i can use inheritance to model operators and remove that big ugly switch in favor of small nice classes. Later on, like 10 years or so Smile | :) it all sorted out, but it took some time (ok, not 10 years maybe Smile | :) ). These days I see interfaces just as a formalization of a natural process; or say common design pattern, or idiom, or paradigm as how we solve certain problems.

Interface programming existed before Java or C# come along. If you know C, than you have already used interfaces but they were implemented in different way. Interface in C is done by using include files. In C one would usually define methods in an include header, and implementations in own files. Since you have implementation in different file(s), you can really have different implementations for same functions. It is just like having different classes implementing same interface in Java.

For example, let say you are making a game, and would like to run it on different systems like Windows, Linux and OSX. You will need a window where you will draw your frames. Say for simplicity a call to openWindow(), will do all we need. What you would do is define your method in say "window.h", then you would make one "window_win32.c" and one "window_x11.c" and yet another "window_osx.c"; as an example. Than we will write different implementaions of that method, one for each platform since they truly are all different. Game that needs to open window for rendering will also include the header, and at compile time you make compiler compile different file depending on what platform you are building. Next game will include pretty much same header file to open its window and so on.

That is an example of interface programming, and since I have done stuff like that, I see it more as a natural solution to a problem, than to something I am obliged to. I have seen some libraries where people use tons of if-defs in the source to intertveen all 3 platforms in same source file. God that is ugly and impractical! Having each platform in different file makes life sooo much easer later on when you have to fix just one platform.

It might seem like a bit long shot to interface xplanation, but it is not. Iterfaces are about modelling and separating model from the implementation. In my little example above, the game does not care about how different platforms implements openWindow(), game is just interesting in what it does; it just wants to have a window on the screen.

In Java and C# (C# was pretty much blue-print copy of java when it first came), interfaces have formal syntax that is not tied to a file, but usage is pretty similar: you declare few mothods, and then use interfaces in classes that needs to work towards that interface.

If we would make a game in Java, we would probably do something like:

public interface GameWindow { ... }

class X11Window implements GameWindow { ... }
class OSXWindow implements GameWindow { ... }
class W32Window implements GameWindow { ... }

class QuakeWindow extends ???? { ... } Smile | :)

Nope, we would write something like:

class Quake {
GameWindow quakeWindow = toolkit.getWindow(X11); (or something in that manner ...)
}

Well ... sort of .. what I wish to illustrate is that our window classes have role of implementation files in C.

You mention something about properties in your articles, but I haven't see anything about them in your article. I don't know about other people, but I see properties as another notation for interfaces. It is actually just syntatic-sugar, a little shorthand to write things faster, but they do declare an class interface (or part of it), in its own special way.

When I was lerning Java, C# wasn't even thought of at Microsoft, they used hapily Java at the time (too frisky for Sun's taste). Java was relatively young language, and nobody really thought of properties. They still don't exist in Java (really why - they are great tool???).
One of OOP step stones is data-hiding. Data hiding is a tool to help with maintance of applications. At the time it was very aggressively advertised argument for java by Sun and many OO purists. The idea is that one should never define any public field (variable), only methods. All data should have accessor methods! At my course we were forbidden to have any public fields since our proffessors wanted to teach us "proper" object-oriented programming. So we were in that hell of sett-gett everything.

The idea is really good: as long as nobody uses class fields you can change the underlaying implementation. For example:

class Person {
public int getAge(){ return age; }
private int age;
}

So now we can only access age variable (or class member as in more ms parlance) through its methods. The only thing is it is very annoying! Classical exemple of vector class is really more illustrative:

Consider an class vector that have say 3 floats as 3d coordinates:

class Vector {
public:
setX(...);
getX(...);
setY(...);
...

private:
float x,y,z;
}

Using this class would be very annoying. I don't remember the name of person that first came up with this example, but it is very famous paper and it is taken up in few books that I have red. You have to do things like: a.setX(b.getX()), instead of doing: a.x = b.x. (There is very famous raytracer (and book), that actually implements all its vector, point, geomtry and other classes as above Smile | :) ).

The thing is that setter and getter does not really hide data; bc user of the class can both read and change data. However they do allow you to change class if you have to, without changing class interface; so for example one mihgt do

class Person {
public int getAge(){ return now() - bday; }
private Date bday;
}

This is of course artificial example, but it is just an illustration.

So how to get around that annoyance of being object-oriented and help with maintance of code by hiding data, and yet have ease of use? Well think of what those variables are? They are actually a class interface, we can see tham as class properties. An orange have certain properties: it has colour, weight, density and so on. Such very object in Java or C# has its properties: a sett of public visible methods and variables. By the way this publicly visible set of properties is the class interface, since it is what clients of the class vill use. Thus it is an implicit interface. It will become clear why I am pointing it out when I got to next illustration. For now let us finnish with properties.

C# makers come up with brilliant idea to encapsulate that notion of a property as a real property. Thus you define a propertie with a keyword, and you really are implementing a method that you later on can change or redefine as you like, and users of the class can use that method as if they are using the field of the class. So now we can do:

class Vector {

public int x {
get { return v[0]; }
set { v[0] = x; }
}

public int y { .... }
public int z { ... }

private int[3];
}

Now we can use class Vector as: Vector a(1,2,3); Vector b(); b.x = a.x; b.y = a.y; and so own.

Property in C#, as seen in code above, hides implementation from its interface. They combine OO principle of data hiding with ease of access, so they are actually just syntax sugar, and not really a new thing.

I said, that public methods and members are a class properties. They are also class interface, since they are how we access and talk to this class. When we write our programs, we are declaring objects and then manipulating them by using their public class methods. Also we really are thinking in terms of class interfaces, without maybe noticing it. We don't care at all about private data; we can't access it anyway. Objects can do thing(s) for us, and that service is provided by means of objects public methods and variables. Thus we can really see this as of thinking in class interface terms, and we can formalize that concept further by really putting that stuff into an interface. A class is just an implementation and we don't even have to care about the class while we are modelling our program. We can design our programs in terms of only interfaces between components (objects). Sounds maybe abstract, but interfaces are actually a modelling tool. We are not interested about platform dependent details (class implementations), but what operations we need to solve our problem (interfaces).

I also pointed above about implicit interfaces and properties being just another name for an interface. Well they are not exactly the same, since a propertie is more class specificall (it really is an iplementation); but properties are used to export an interface to the outer world.

How does inheritance come into picture. Well similar to above reasoning, a base class is actually an interface exported to the rest of hierarchy. When we subclass a base class, there is a reason why we do that. Here is a point where things gets little muddy. If you read older books on object oriented programming, inheritance is sometimes seen as code-reuse in a copy-paste manner. The idea is that one implement functionality he/she needs, and than adds new functionality in subclass when needed, and thus building blocks of (re)usable code. I think that now prevalent view on inheritance is to see it as a modeling tool, just as interfaces. In this vew, the base class is the interface to levels above (which usually are drawn as below the base class in uml diagrams).

In java we can for example write:

Object o = new String("hello");

Now just as in case with interface, we can call methods that are declared in Object.That is also my conclusion what interfaces are about: modelling and separation of implementation from the model. It is even more clean in C++ that does not have interface keyword at all. Interfaces in C++ are implemented with inheritance. An interface in c++ is an class with all methods declared as "pure virtual" (abstract in Java/C#). Really - coulnd't C++ commitee work on that syntax a bit? Please?

I don't know if I was any clear; I have written this in one go, just as it popped in my mind. I wanted to give view from different angles, and to illustrate interface concept from practical approach. I haven't touched generic (template) classes. They are what B.Eckel doubed to "implicit interface". I see actually template class just as standard class, and I think that conceptual difference is that template object "expects" an interface, while class "exports" an interface, but they are both implicit in terms that there is no explicit specification to compiler.¨

I belieave that solving problems (writing programs) and design to solution should be done in terms of interface. Many class diagrams would be much easier to read and undertand if they only contained relations and interactions between interfaces involved, rather than to think in terms of concrete classes.

This has got long, and I definitely have to go to sleep Smile | :) I hope i didn't got too confusing, I know this is hastly written is it poped into my mind, so it will probably be unclear. Also english is not my language, so i guess I express myself a bit clumsy at times. I have no pretensions to give a "real" picture of interface or to show how things should be explained or teached; I am just trying to give different angles to the concept.

Before I finish, I would like to recommend everyone to take a look in Haskell; not to go over to Haskell full-time (if you can do it! Smile | :) ), but to see a different implementation of all those terms. You will see how powerfull interface programming is, and yet there is no explicit declaration of interface in haskell. There is something similar called type classes, which is kind-a cross over between templates and java/c# interface, but very powerfull and elegant mechanism. The power of interface is in removal of implementation details while designing/modelling the program (I think).
GeneralRe: A bit practical look on interfaces Pin
hammerstein0523-Apr-12 0:26
hammerstein0523-Apr-12 0:26 
QuestionMy vote of 4 Pin
Reiss13-Nov-11 4:46
professionalReiss13-Nov-11 4:46 
GeneralMy vote of 4 Pin
Sandesh M Patil12-Jul-11 0:58
Sandesh M Patil12-Jul-11 0:58 
GeneralRe: My vote of 4 Pin
hammerstein0522-Apr-12 1:28
hammerstein0522-Apr-12 1:28 
QuestionYou cannot create an object of an interface? Pin
n.easwaran1-Feb-10 19:34
n.easwaran1-Feb-10 19:34 
AnswerRe: You cannot create an object of an interface? Pin
RobiProfisoft1-Feb-10 21:06
RobiProfisoft1-Feb-10 21:06 
QuestionRammstein fan? Pin
User 43300281-Feb-10 14:40
User 43300281-Feb-10 14:40 
AnswerRe: Rammstein fan? Pin
hammerstein052-Feb-10 0:48
hammerstein052-Feb-10 0:48 
GeneralAuto-properties Pin
Stanislav Georgiev29-Jan-10 23:31
Stanislav Georgiev29-Jan-10 23:31 
GeneralRe: Auto-properties Pin
MR_SAM_PIPER1-Feb-10 15:50
MR_SAM_PIPER1-Feb-10 15:50 
GeneralRe: Auto-properties Pin
Stanislav Georgiev1-Feb-10 20:19
Stanislav Georgiev1-Feb-10 20:19 
GeneralRe: Auto-properties Pin
MR_SAM_PIPER2-Feb-10 11:39
MR_SAM_PIPER2-Feb-10 11:39 
GeneralInterfaces versus inheritance PinPopular
supercat928-Jan-10 7:04
supercat928-Jan-10 7:04 
GeneralInterfaces for Data Objects Pin
HoyaSaxa9328-Jan-10 2:12
HoyaSaxa9328-Jan-10 2:12 
RantSuggestion... No... Flame! Pin
Roguer128-Jan-10 1:49
Roguer128-Jan-10 1:49 
GeneralRe: Suggestion... No... Flame! Pin
hammerstein0528-Jan-10 2:06
hammerstein0528-Jan-10 2:06 
GeneralRe: Suggestion... No... Flame! Pin
Diamonddrake29-Jan-10 12:25
Diamonddrake29-Jan-10 12:25 
GeneralYou could also include Pin
Muneeb R. Baig27-Jan-10 20:42
Muneeb R. Baig27-Jan-10 20:42 
GeneralRe: You could also include Pin
hammerstein0528-Jan-10 0:52
hammerstein0528-Jan-10 0:52 
GeneralYou could include Pin
Ennis Ray Lynch, Jr.27-Jan-10 18:36
Ennis Ray Lynch, Jr.27-Jan-10 18:36 
GeneralRe: You could include Pin
hammerstein0528-Jan-10 1:07
hammerstein0528-Jan-10 1:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.