Programmers : Why do Interfaces exist?

BobTheSlob

Limp Gawd
Joined
Feb 16, 2002
Messages
291
I'm currently in CS1322 at Georgia Tech, and we frequently get asked questions about Interfaces on tests, and in homework. And I just can't for the life of me understand why they exist? I'm sure there is a good reason for them existing, but to me a bunch of methods with no bodies really doesn't accomplish much. Anyone care to enlighten me?
 
Interfaces exist to encourage/enforce people to use a library as intended, rather than in some kludgey way that only they could figure out, by say, using methods or data structures that are only intended to be called or used within the module itself. It helps with maintenace(nobody is breaking their program by using methods from the module that they shouldn't touch), readability(the module is, in theory, used in the same way by everyone), software design(since you're not guessing which methods to use), and modularity(module for similar purposes should have similar interfaces, though not necessarily similar implementations).

I probably messed something up in that description, STL and others can definately explain this better.
 
Here is an example of one use for interfaces:

Suppose you want to make a new sorting algorithm in Java. You also want people to be able to use it on whatever classes they may create. In order to do this, you need some guarantee that there is a method in their class that allows them to compair to of their objects.

You don't want them to have to modify your sorting code every time they have a new class they want to use it with; changing object types, casts, etc. This is where interfaces come in. You can declair an IMySortable interface with a CompairTo(...) method. Then all anyone who wants to use your algorithm needs to do, is implement the IMySortable interface, and thus have a CompairTo(...) method. In your sorting code, you would simply reference the interface name to sort the objects:

Code:
public MySort
{
    public static void SortAscending(IMySortable[] list)
    {
     ...
    }
}

Since list implements the IMySortable interface, you know there has to be a ComairTo(...) method, and you can safely use that method to compair the objects.

Please don't pick at my java pseudocode, I just woke up, and I havn't touched Java in about a year.
 
Same reason there are buttons on a cd player. You dont care how the thing works, as long as you know which buttons to push to have it do whatever.
 
> to me a bunch of methods with no bodies really doesn't accomplish
> much.

An abstract base class (in Java, an "Interface", though remember that Java sucks) is a description of services that a class will provide. For example, McDonald's provides the service of making a plain double cheeseburger. So does Burger King. To me the customer, it doesn't matter how they go about providing that service, as long as it produces what they guaranteed. If all they guarantee me is a plain double cheeseburger for $1, then I don't care if they pull one out of the freezer and nuke it, or if they slaughter the cow right then and there and make the burger out of ground-up prime rib. But I will care if they put ketchup on it GOD DAMN IT.

Ahem.

Interfaces in general are the key insight in data abstraction. It also turns out that interface inheritance is the only reasonable kind of inheritance you should ever use in object oriented programming.

[Velox]
> Suppose you want to make a new sorting algorithm in Java.

God, Java sucks.

C++ solves this problem with functors. And it solves it better.

> In order to do this, you need some guarantee that there is a method
> in their class that allows them to compair to of their objects.

C++ doesn't require this guarantee. That sounds like a small thing. It is not.

[Whatsisname]
> Same reason there are buttons on a cd player. You dont care how the
> thing works, as long as you know which buttons to push to have it
> do whatever.

This is perhaps the best explanation of interfaces that I have heard in a long time.
 
Originally posted by Whatsisname
Same reason there are buttons on a cd player. You dont care how the thing works, as long as you know which buttons to push to have it do whatever.

See that would make sense, but, methods in interfaces don't have a body. Like..

public interface clown
{
public void makeKidsLaugh() {}
public void causeAdultNightmares() {}
public int throwPie() {}
}

What good does this do? If I go ahead and implement the interface like so...

public class party implements clown

then I have to define those methods' bodies! What did the interface achieve? Why bother implementing them? I don't understand :(
 
I'll use a reallife Java example (bare with me, i only know java)

You have Comparable interface. You make 3 classes: x, y, z

You want to have a program that is malleable enough so that you can use compareto on either x, y, or z depending on what's fed, so you put as the parameter an object of type Comparable.
 
> methods in interfaces don't have a body

They say what classes implementing that interface should do.

I don't really believe in inheritance though, even interface inheritance. I haven't found a use for OO gook in my own programming yet.
 
Basically, inheritance allows old code to call new code. That's the whole point of dynamic polymorphism.

For example, you can add plugins to a program simply by relinking, not by recompiling.
 
Originally posted by BobTheSlob
See that would make sense, but, methods in interfaces don't have a body. Like..

public interface clown
{
public void makeKidsLaugh() {}
public void causeAdultNightmares() {}
public int throwPie() {}
}

What good does this do? If I go ahead and implement the interface like so...

public class party implements clown

then I have to define those methods' bodies! What did the interface achieve? Why bother implementing them? I don't understand :(

Let my try again with another example.
Suppose you have code like this

Code:
class party
{
    private static Guests kids;
    private static Clown proffesional

    public static void Main()
    {
        kids = new Guests();
        proffesional = new Clown();

        while( kids.count > 1)
            proffesional.makeKidsLaugh();
    }

Now this is all fine and good, but what happens if you don't want a Clown? Suppose you want a Magician? Then you have to go back, and edit your code, and everywhere you delcaired a Clown, every where you casted something to a Clown you have to change it to a Magician. The same thing happens if you want a Mime, or a Juggler, or an STL. And suppose you don't know what you want yet? Suppose you have to pick which type of entertainer you want at runtime? Then what do you do? You can't just have it be an Object, because Object doesn't contain the makeKidsLaugh() method. This is where interfaces come in. You simply make an entertainer interface:

Code:
public interface Entertainer
{
    public void makeKidsLaugh() {}
}

and rewrite your code as follows:
Code:
class party
{
    private static Guests kids;
    private static Entertainer proffesional

    public static void Main()
    {
        kids = new Guests();
        proffesional = new Clown();

        while( kids.count > 1)
            proffesional.makeKidsLaugh();
    }

Now, if you want to change the entertainer type to a Mime, or a Juggler, or any other class that implements the Entertainer interface, you have to change one line. Also, you can have the user pick the type of entertainer at runtime:

Code:
class party
{
    private static Guests kids;
    private static Entertainer proffesional

    public static void Main()
    {
        kids = new Guests();
        proffesional = getEntertainer();

        while( kids.count > 1)
            proffesional.makeKidsLaugh();
    }

    private static Entertainer getEntertainer()
   {
        // Prompt user to input what type of entertainer they want;
        
        swich(input)
        {
        case "Clown":
            return new Clown();
        case "Mime":
            return new Mime();
        case "Grass":
            return new Grass();
        ... etc...
        }
   }

Hopefully, this psuedocode helps clear things up, at least a little bit.

And yes, STL, Java sucks. :p
 
Of course the problem with Interfaces is that they do not require either client (Interface using class/function) or server (Interface implementing class) to use/implement the Interface sensibly.

Furthermore, some frameworks document Interfaces either poorly or thinly. They also behave poorly when you need to use two distinct libraries together, for example a set of sorting or statistics algorithms from one library and concrete types from another. In general, you would need to create a new class of your own which implements the proper Interfaces and forwards the calls to a contained or extended instance of a class from the other library. If either library's documentation contains inaccuracies or omissions, you could find yourself in a difficult position.

In short, Interfaces require useful and comprehensive documentation, but may be undermined by inaccurate or incomplete documentation elsewhere.

OTOH, Interfaces are a great improvement over MandatoryBaseClassesWithNonVirtualMemberFunctionsAndState, for example CWnd in MFC, which requires you to override virtual functions AND call the base class function (either at the beginning, middle, or end of your override, this will depend on what you are trying to do, sometimes you need to manipulate your parameters), and is generally difficult to use.

The C++ functor idiom is rather useful in some instances, for example when using several libraries which do not know about each other, but it suffers some problems. There is no generally accepted technique for extending a functor-using library at runtime, and the most promising current solution for that would probably involve using boost::function, which would be fine for tasks that require a small number of functors, but would be more expensive in codespace, runtime, and runtime memory usage for moderate to large numbers of functors. Additionally, even if the Modern C++ community developed and demonstrated such an idiom, I would expect that it would remain relatively unknown for several years, while Interfaces are relatively well-known today.
 
> There is no generally accepted technique for extending a
> functor-using library at runtime

... dynamic polymorphism. operator() can be virtual.
 
There's a little bit better of an example to use. Ever wonder why games can(or used to) use multiple rendering technolgies(DirectX, OpenGL, etc). It's all done using a interface class and the deriving your openGL. DirectX, etc class from that interface. That way you can call RenderStuff() and various render functions without worrying what API you are using.

This technique is also great for portability, for instance I have two separate socket classes for something I'm writing right now, one for when I'm using Unix and I need to use berkley sockets, the other for when I use WinSock in windows.
 
> This technique is also great for portability, for instance I have
> two separate socket classes for something I'm writing right now,
> one for when I'm using Unix and I need to use berkley sockets, the
> other for when I use WinSock in windows.

Mlar. I use a minimal set of #ifdef's and the same code can be compiled to use BSD Sockets or Winsock 2.
 
Originally posted by Whatsisname
Same reason there are buttons on a cd player. You dont care how the thing works, as long as you know which buttons to push to have it do whatever.

hah... good explanation

my prof. always used to say this:

Interface in Java is like an interface in a car. Every car has the same interface: a steering wheel, a gas pedal and a brake pedal (some add more functions to this, but that's besides the point)

If you know how to drive one car (know how to use the interface), you can drive almost all other cars...

In Java, if you know how to sort one type of objects, you know how to sort anything else that uses the same interface....

Then, the prof. would always apply the car analogy to the student's code.... My 'car' for example, would be steered using a 'left' button located in the trunk, a 'right' joystick on the hood, a gas sensor in the seat that required jumping up and down, and would have no brakes :D
 
Originally posted by STL
Mlar. I use a minimal set of #ifdef's and the same code can be compiled to use BSD Sockets or Winsock 2.

Yeah, but for what I'm doing the unix version involves threads, the windows version is more of a debug version when I don't have access to my machine at home.
 
Back
Top