Why Interfaces?

Take a look at the follwing page about Interfaces from Microsoft:

http://msdn.microsoft.com/en-us/library/64syzecx.aspx

I'm really, really trying to see the benefit of interfaces but am failing to see their point.

Using the example at the bottom of the page, if I remove the ": IEmployee" from the "public class Employee : IEmployee" everything still works fine; making it seem to me that creating the interface is a waste of time and resources.

So, can anyone explain, in laymen's terms, why would I ever bother to create interfaces? If the answer is "it's good practice" then I will continue to not use them unless there is some substantial performance benefit.

Please shed some light...
// Why is any of this...
interface IEmployee
{
    string Name
    {
        get;
        set;
    }

    int Counter
    {
        get;
    }
}
//...necessary??

public class Employee : IEmployee // Remove : IEmployee and is still works
{
    public static int numberOfEmployees;

    private string name;
    public string Name  // read-write instance property
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }

    private int counter;
    public int Counter  // read-only instance property
    {
        get
        {
            return counter;
        }
    }

    public Employee()  // constructor
    {
        counter = ++counter + numberOfEmployees;
    }
}

class TestEmployee
{
    static void Main()
    {
        System.Console.Write("Enter number of employees: ");
        Employee.numberOfEmployees = int.Parse(System.Console.ReadLine());

        Employee e1 = new Employee();
        System.Console.Write("Enter the name of the new employee: ");
        e1.Name = System.Console.ReadLine();

        System.Console.WriteLine("The employee information:");
        System.Console.WriteLine("Employee number: {0}", e1.Counter);
        System.Console.WriteLine("Employee name: {0}", e1.Name);
    }
}

Open in new window

infotechelgAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
You can't see the benefit because that is a horrible example!  =\

To see the benefit of Interfaces you'd need to declare a variable of the Interface Type and then have more than one type of class that implemented that Interface.  The classes implementing the Interface could be very different, but when cast to the Interface type, they could all be acted upon in all the same way (because they all implement the common interface).  This allows your base code to remain unchanged as you are acting upon the Interface Type but allows any number of new classes to be introduced...as long as they Implement said Interface.

Hope that helps...
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jens FiedererTest Developer/ValidatorCommented:
The point doesn't really come across if you are just doing a small project.  Interfaces become most useful useful when you are bringing code from different sources together.

An example would be, for example, using controls made by a 3rd party developer like Infragistics.

Say you are using their UltraDockManager class to put together your user interface, but you don't like the way their "Close" buttons look.

Infragistics lets you assign a "DisplayFilter" property to your dock manager, which has to be from a class that inherits from their IDisplayFilter interface.  

YOU are the one that writes this new class.  If you DON'T support IDisplayFilter in your class, you will get an error when you try to assign an object of your class to the DisplayFilter property, so you have to use it whether you like it or not.  Then one of the methods on your class (required by IDisplayFilter) can take care of drawing the Close buttons differently.

Interfaces are ways of defining how to work with your code from completely outside your code.
0
infotechelgAuthor Commented:
"You can't see the benefit because that is a horrible example!  =\"

Ha! Thanks, Microsoft.

I'll look over both of your responses carefully.
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

infotechelgAuthor Commented:
jensfiederer & Idle_Mind,

both of your responses make sense. Do you have any real-life examples (code) that you could share? I'm more of a visual learner (hence the reason why the Microsoft Example was so bad!).

Cheers,
Jeremy
0
Jens FiedererTest Developer/ValidatorCommented:
My example WAS a real-life example, it's something I had to do just a couple of weeks ago - it was actually DrawFilter, not DisplayFilter though.


Here is a story from one person who did something similar:

http://forums.infragistics.com/forums/p/21808/79342.aspx

0
Jens FiedererTest Developer/ValidatorCommented:
A simpler example than Infragistics would be in existing .NET code....

the Sort method on generic collections such as list allows you to pass in an "IComparer".

YOU can write the class/method that does it, it just has to conform to the IComparer interface.
0
infotechelgAuthor Commented:
I know it was. I meant does any one have any CODE examples of this working in real life so i can see how it works.
0
infotechelgAuthor Commented:
Thanks for your insight. This should get me on the right track.
0
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
Maybe this silly example will help...

Not that each type of pet has its own unique abilities, and other than the Interface, have nothing else in common.

The code in Main() is ONLY using the Interface Type, yet we are able to interact with all these disparate types in the same way; asking each to "speak".  We could add an infinite number of other animals, even from outside sources as jensfiederer points out, and the base code would not change.  We don't care what the actual underlying type of the animal is as long as it satisfies the conditions of our Animal Interface.

Also note that the classes could implement any number of other Interfaces as well and it wouldn't change the code in this project.  This is typically how we get around the fact that .Net does not allow multiple inheritance.

Anyhoo, here's the sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            List<Animal> animals = new List<Animal>();
            animals.Add(new Dog());
            animals.Add(new Cat());
            animals.Add(new Snake());
            animals.Add(new Fish());

            foreach (Animal pet in animals)
            {
                Console.WriteLine(pet.Speak());
            }

            Console.WriteLine("Press enter to quit.");
            Console.ReadLine();
        }

    }

    interface Animal
    {
        string Speak();
    }
    
    public class Dog : Animal
    {

        string Animal.Speak()
        {
            return "Woof!";
        }

        public void PeeOnFloor()
        {
            Console.WriteLine("Unexpected output!");
        }

    }

    public class Cat : Animal
    {

        string Animal.Speak()
        {
            return "Meow!";
        }

        public void EatHousePlants()
        {
            Console.WriteLine("Unexpected input!");
        }

    }

    public class Snake : Animal
    {

        string Animal.Speak()
        {
            return "Hiss!";
        }

        public void BiteOwner()
        {
            Console.WriteLine("Invalid action attempted!");
        }

    }

    public class Fish : Animal
    {

        string Animal.Speak()
        {
            return "Bloop!";
        }

        public void PeformAcrobatics()
        {
            Console.WriteLine("Floating upside down isn't a trick!");
        }

    }

}

Open in new window

0
käµfm³d 👽Commented:
Here's my attempt at a "real-world" example  : )


Think about water faucets. How do you turn them on? Some single dials that spin; some have two handles, one for each temperature, some have chains that you pull to turn on the water. All of these designs have the same operations in common--turn water on; turn water off. These operations could thusly be defined in an interface.

interface IFaucet
{
    void TurnOnWater();
}

Open in new window


This interface is the contract between any class that implements IFaucet. This contract says, "if you implement IFaucet, then you WILL have two functions called 'TurnOnWater' and 'TurnOffWater.' Because you know that an IFaucet has these two methods, any class that implements IFaucet should have these two methods.

The wonderful thing about interfaces is that you don't care how, in this particular example, a faucet turns on the water; only that it does so. So for each class that implements IFaucet, we can different concepts of turning water on and off. For example:

Chain Faucet
class ChainFaucet : IFaucet
{
    enum ChainState
    {
        ChainPulled,
        ChainReleased,
    }

    private ChainState _state;

    #region IFaucet Members

    public void TurnOnWater()
    {
        this._state = ChainState.ChainPulled;
    }

    public void TurnOffWater()
    {
        this._state = ChainState.ChainReleased;
    }

    #endregion
}

Open in new window


DualKnobFaucet
class DualKnobFaucet : IFaucet
{
    private bool _hotKnob;
    private bool _coldKnob;

    #region IFaucet Members

    public void TurnOnWater()
    {
        this._hotKnob = true;
        this._hotKnob = true;
    }

    #endregion

    #region IFaucet Members


    public void TurnOffWater()
    {
        this._hotKnob = false;
        this._hotKnob = false;
    }

    #endregion
}

Open in new window


Single Knob Faucet
class SingleKnobFaucet : IFaucet
{
    private int _degreesFromOff;

    #region IFaucet Members

    public void TurnOnWater()
    {
        this._degreesFromOff = 30;
    }

    public void TurnOffWater()
    {
        this._degreesFromOff = 0;
    }

    #endregion
}

Open in new window


So just as when you use the sink in your bathroom, you don't care how the faucet allows water to start flowing; you only care that it does allow water to flow. Each faucet implementation above turns on the water in its own special way, but to the outside world, we only know that the faucet turns water on and turns water off.

Also with interfaces, you get the benefit of treating each implementation of IFaucet generically, that is, as an IFaucet rather than, for instance, a DualKnobFaucet. This allows your code to be more abstract. This is akin to saying, "honey, will you turn off the faucet," rather than saying, "honey, will you turn off the dual-knob faucet?" Both mean the same thing, but in the former you are referring to the generic name. This comes in handy in code as well at times.
0
käµfm³d 👽Commented:
IFaucet above should have been defined as this:
interface IFaucet
{
    void TurnOnWater();

    void TurnOffWater();
}

Open in new window

0
käµfm³d 👽Commented:
Both mean the same thing...

I should rephrase this as, "Both accomplish the same goal..."
0
infotechelgAuthor Commented:
Wow, thanks a lot everyone!
0
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
Going back to the inheritance issue, both of these problems could have been solved by creating a base type of Faucet or Animal, and then the Derived class could have provided its own specialized way of accomplishing the task at hand by Overriding the base code.

***BUT*** since you can only Inherit from ONE Class, this limits what we can do in some cases.  If either of the classes in these scenarios were required to have already been derived from some other class...we would be screwed.  By using the Interface approach we can now allow the class to Inherit from something else while still being able to be treated as our Interface type.

Remember, you can Implement as many Interfaces as you want, but can only Inherit from one thing.
0
anarki_jimbelSenior DeveloperCommented:
It's very interesting question. And all programmers ask it sooner or later.

Please see the discussion. BTW, the answer from Idle Mind was accepted - he know all about interfacers :)

In the discussion above I had some examples, but the question was asked back:

"...class MyTest : ICompareable ()

I would have methods in there like for example:

Public int CompareTo

Now, I can have that as well without the need for the Interface. "

Yes, we may create a class and put CompareTo method without interfaces. But it has no use.
Say, you put objects of your class to a list and want to sort them. How you can do this? OK, if List can see that your class implements IComparable, it can call CompareTo method and sort your objects. If your class does not implement IComparable, the List has NO idea how to sort your objects (it simply can't find CompareTo method that does not belong to a IComparable  interface. Result - can't sort objects.

This is just one example. Again - see the discussion above and more from Idle Mind and me :)
0
anarki_jimbelSenior DeveloperCommented:
Ha, guys, you're quick :)

People love interfaces! :)
0
käµfm³d 👽Commented:
By using the Interface approach we can now allow the class to Inherit from something else while still being able to be treated as our Interface type.

Technically speaking, we are not inheriting anything from the interface since interfaces can't have any members of their own--you don't even define access modifiers for the methods/properties listed in the interface--but for the sake of this discussion you can think of it as inheriting.
0
infotechelgAuthor Commented:
Thanks a ton, everybody. I really appreciate it.
0
käµfm³d 👽Commented:
@Idle_Mind

Please don't think I was taking a shot at you in http:#35264305 ...  I just wanted to delineate the difference between inheriting a base class and implementing an interface  : )
0
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
No problem...  =)

I was thinking more along the lines of something like below where the class already Inherits from something else...but we can still Implement as many Interfaces as we want:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            BaseClass bc = new DerivedClass();

            Console.WriteLine(bc.Speak());
            ((SomeInterface1)bc).SomeAction();
            ((SomeInterface2)bc).SomeOtherAction();

            Console.WriteLine("Press enter to quit.");
            Console.ReadLine();
        }

    }

    public class BaseClass
    {
        public virtual string Speak()
        {
            return "Hello World!";
        }
    }

    interface SomeInterface1
    {
        void SomeAction();
    }


    interface SomeInterface2
    {
        void SomeOtherAction();
    }

    public class DerivedClass : BaseClass, SomeInterface1, SomeInterface2
    {

        public override string Speak()
        {
            return "Hello Derived World!";
        }

        void SomeInterface1.SomeAction()
        {
            Console.WriteLine("SomeAction()");
        }

        void SomeInterface2.SomeOtherAction()
        {
            Console.WriteLine("SomeOtherAction()");
        }

    }

}

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.