views:

248

answers:

6

I'm building a decent sized application in ASP.NET/VB.NET with various objects... I've never used interfaces before, and a fellow programmer balked when I mentioned this to him. Can anyone give me a quick overview on how they're used, what they're used for, and why I would use them? Maybe I don't need to use them for this project, but if they would help, I surely would love to try.

Thanks so much!

+2  A: 

Interfaces basically allow you to define a type's contract without specifying its implementation.

The idea is that if you know that a given type implements a certain interface it is guaranteeing that certain methods and properties are members of that type.

So any type that implements the following interface:

Interface ISpinnable
    Sub Spin()
End Interface

Would have to implement the Spin method. But the caller of this type that implements ISpinnable does not care about how it is implemented, it just cares that the method is there. Here is a type that implements ISpinnable:

Class Top Implements ISpinnable
    Sub Spin()
     ' do spinning stuff
    End Sub
End Class

The benefit to this is that you can create method arguments of type ISpinner and allow the caller of these methods to pass any type to you as long as it implements the interface. Your method is no longer tightly coupled to the concrete type that the caller is using.

Andrew Hare
Thanks for this example.. so let's say I'm building an order processing system.. i have the overall order which consists of invoices, purchase orders, and credit forms. Would I have the forms implement something like IForm with methods like Save(), Print(), etc?
Jason
Exactly! That sounds like a solid application of interfaces.
Andrew Hare
+1  A: 

An interface is a contract without an implementation. It allows you to define what a type will look like without indicating what the implementation of that type is.

This allows you to have various implementations of an interface, which would suit your particular needs.

A good example is the IComparer(Of T) interface. You can have one implementation that will compare two items based on which is greater, and then another which will return a value based on which is lesser.

Then, you could pass one or the other to the static Sort method on the Array class to sort your items in ascending, or descending order, respectively.

casperOne
Thank you for your answer! This helps me understand a bit better.
Jason
+6  A: 

Once you "get" interfaces, OOP really falls into place. To put it simply, an interface defines a set of public method signatures, you create a class which implements those methods. This allows you generalize functions for any class which implements a particular interface (i.e. classes which have the same methods), even if those classes don't necessarily descend from one another.

Module Module1

    Interface ILifeform
        ReadOnly Property Name() As String
        Sub Speak()
        Sub Eat()
    End Interface

    Class Dog
        Implements ILifeform

        Public ReadOnly Property Name() As String Implements ILifeform.Name
            Get
                Return "Doggy!"
            End Get
        End Property

        Public Sub Speak() Implements ILifeform.Speak
            Console.WriteLine("Woof!")
        End Sub

        Public Sub Eat() Implements ILifeform.Eat
            Console.WriteLine("Yum, doggy biscuits!")
        End Sub
    End Class

    Class Ninja
        Implements ILifeform

        Public ReadOnly Property Name() As String Implements ILifeform.Name
            Get
                Return "Ninja!!"
            End Get
        End Property

        Public Sub Speak() Implements ILifeform.Speak
            Console.WriteLine("Ninjas are silent, deadly killers")
        End Sub

        Public Sub Eat() Implements ILifeform.Eat
            Console.WriteLine("Ninjas don't eat, they wail on guitars and kick ass")
        End Sub
    End Class

    Class Monkey
        Implements ILifeform


        Public ReadOnly Property Name() As String Implements ILifeform.Name
            Get
                Return "Monkey!!!"
            End Get
        End Property

        Public Sub Speak() Implements ILifeform.Speak
            Console.WriteLine("Ook ook")
        End Sub

        Public Sub Eat() Implements ILifeform.Eat
            Console.WriteLine("Bananas!")
        End Sub
    End Class


    Sub Main()
        Dim lifeforms As ILifeform() = New ILifeform() {New Dog(), New Ninja(), New Monkey()}
        For Each x As ILifeform In lifeforms
            HandleLifeform(x)
        Next

        Console.ReadKey(True)
    End Sub

    Sub HandleLifeform(ByVal x As ILifeform)
        Console.WriteLine("Handling lifeform '{0}'", x.Name)
        x.Speak()
        x.Eat()
        Console.WriteLine()
    End Sub
End Module

None of the classes above descend from one another, but my HandleLifeform method is generalized to operate on all of them -- or really any class which implements the ILifeform interface.

Juliet
this is the best description i've seen for this concept. thank you so much!
Jason
and ninjas totally wail on guitars because they're totally sweet.
Jason
+3  A: 

Since the basics have already been covered, lets move on to practical examples.

Say I'm going to have a Dictionary that stores String keys and Person objects and I'm going to pass this dictionary (actually, the reference to it) to some methods I have.

Now, my receiving method would look something like

Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As Dictionary(Of String, Person))
    ' Do something with myDict here
End Sub

right?

But what if someone invents some new high performance dictionary class? I have to turn around and change every reference to Dictionary to FastDictionary!

However, if I had coded to the interface in the first place, I wouldn't have this problem:

Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As IDictionary(Of String, Person))
    ' Do something with myDict here
End Sub

Now it takes any dictionary!

R. Bemrose
+1  A: 

One of the things interfaces can be useful is browsing through the array of objects of different types but which share the same interface. Can't say for VB, but in C# you can use the handy "is" operator to determine if object's type implements the given interface and it's safe to access methods of that interface by casting. Sorry for C#, but i'll try to put some comments in =))

//we declare 3 different interfaces each requiring to implement one method
                    interface IProgrammer
                    {
                        void WriteCode();
                    }

                    interface ITester
                    {
                         void FindBugs();
                    }

                    interface IWorker
                    {
                         void StartShift();
                    }

        // each programmer will be able to start his shift and write code
                    class Programmer : IWorker, IProgrammer
                    {

                        public void StartShift()
                        {
                          // ...
                        }

                        public void WriteCode()
                        {
                          // ...
                        }

                    }

        // each tester will be able to start his shift and find bugs

                    class Tester : IWorker, ITester
                    {
                        public void StartShift()
                        {
                            // ...
                        }

                        public void FindBugs()
                        {
                            // ...
                        }
                    }

            //then in code you can rely on objects implementing the interface to 
            // be able to do tasks interface requires to do
                    static void Main()
                    {
                        IWorker[] workers = new IWorker[3];
                        workers[0] = new Programmer();
                        workers[1] = new Tester();
                        workers[2] = new Tester();

       // now we can browse through array of different workers because they all share
       // the IWorker interface
                    foreach(IWorker worker in workers)
                    {
                        // All IWorkers can StartShift so we access its methods without casts
                        worker.StartShift();
                        if(worker is IProgrammer)
                        {
                            // Since that worker also implements IProgrammer
                            // we cast worker as IProgrammer and access IProgrammer method(s)
                            (worker as IProgrammer).WriteCode();
                        }
                        if(worker is ITester)
                        {
                            // Same,
                            // we cast worker as ITester and access ITester method(s)
                            // handy! =)
                             (worker as ITester).FindBugs();
                        }
                    }
æther
this is very helpful! thank you so much :)
Jason
+1  A: 

A classic example is the Data Layer where you use it to support multiple database format. This was actually very useful before ORMappers came into the picture in mainstream programming.

Your interface just tells what type of method and properties your object has, the object itself then has to implement these methods.

IMyDatabase myDb;

switch case myDbFormat {
     case "mysql":
        myDb = new MyDbMySql();
        break;
     case "mssql" :
        myDb = new MyDbMsSql();
        break;    
}

myDb.SaveToDatabase(some data)

Ofcourse the myDb classes have to implement the ImyDatabase Interface. I assume you can see how useful this is :).

Morph