views:

1042

answers:

13

So lets say I have this interface:

public interface IBox
{
   public void setSize(int size);
   public int getSize();
   public int getArea();
  //...and so on
}

And I have a class that implements it:

public class Rectangle implements IBox
{
   private int size;
   //Methods here
}

If I wanted to use the interface IBox, i can't actually create an instance of it, in the way:

public static void main(String args[])
{
    Ibox myBox=new Ibox();
}

right? So I'd actually have to do this:

public static void main(String args[])
{
    Rectangle myBox=new Rectangle();
}

If that's true, then the only purpose of interfaces is to make sure that the class which implements an interface has got the correct methods in it as described by an interface? Or is there any other use of interfaces?

+1  A: 

you could do

Ibox myBox=new Rectangle();

that way you are using this object as Ibox and you dont care that its really Rectangle

01
+17  A: 

Interfaces are a way to make your code more flexible. What you do is this:

Ibox myBox=new Rectangle();

Then, later, if you decide you want to use a different kind of box (maybe there's another library, with a better kind of box), you switch your code to:

Ibox myBox=new OtherKindOfBox();

Once you get used to it, you'll find it's a great (actually essential) way to work.

Another reason is, for example, if you want to create a list of boxes and perform some operation on each one, but you want the list to contain different kinds of boxes. On each box you could do:

myBox.close()

(assuming IBox has a close() method) even though the actual class of myBox changes depending on which box you're at in the iteration.

morgancodes
There is nothing in this answer that is exclusive to *Java interfaces*. The same applies equaly well to abstract classes, or even concrete ones. I would expect a good answer to mention the ability to implement *multiple* interfaces, and when/why that would be useful.
Rogerio
+3  A: 

Normally Interfaces define the interface you should use (as the name says it ;-) ). Sample


public void foo(List l) {
   ... do something
}

Now your function foo accepts ArrayLists, LinkedLists, ... not only one type.

The most important thing in Java is that you can implement multiple interfaces but you can only extend ONE class! Sample:


class Test extends Foo implements Comparable, Serializable, Formattable {
...
}
is possible but

class Test extends Foo, Bar, Buz {
...
}
is not!

Your code above could also be: IBox myBox = new Rectangle();. The important thing is now, that myBox ONLY contains the methods/fields from IBox and not the (possibly existing) other methods from Rectangle.

Johannes Weiß
Is 'List' supposed to be an interface member?
Click Upvote
List is an interface in the java collections library.
rmeador
List is an interface in the standard Java library (http://java.sun.com/javase/6/docs/api/java/util/List.html). He's just using it to illustrate his point.
Michael Myers
+1  A: 

If you have CardboardBox and HtmlBox (both of which implement IBox), you can pass both of them to any method that accepts a IBox. Even though they are both very different and not completely interchangable, methods that don't care about "open" or "resize" can still use your classes (perhaps because they care about how many pixels are needed to display something on a screen).

Todd R
+9  A: 

The purpose of interfaces is polymorphism, a.k.a. type substitution. For example, given the following method:

public void scale(IBox b, int i) {
   b.setSize(b.getSize() * i);
}

When calling the scale method, you can provide any value that is of a type that implements the IBox interface. In other words, if Rectangle and Square both implement IBox, you can provide either a Rectangle or a Square wherever an IBox is expected.

Apocalisp
Why is the purpose of interfaces polymorphism, if I can already achieve that in Java with subclassing and method overriding?
eljenso
It's the same thing, except that interfaces must omit any implementation. Classes can therefore implement more than one interface.
Apocalisp
I asked, because you could also say that the primary purpose of interfaces is abstraction (i.e. decoupling from implementation), and just like any Java type (be it declared as class or interface) they allow for polymorphism through inheritance.
eljenso
Hey, I never said Java had any kind of conceptual integrity. Type substitution is the purpose of all subtyping. Java happens to have more than one subtyping mechanism, none of which are particularly good.
Apocalisp
I never said anything about conceptual integrity as well. But let's move on. If you can scale every IBox with your method, shouldn't it be an operation declared on IBox: IBox.scale(int)?
eljenso
Why not make it a method on Integer? It doesn't matter to me either way except that the more methods you add to an interface, the more cumbersome it is to implement.
Apocalisp
We wouldn't want to couple Integer to IBox, that's why we don't make it a method on Integer. And the number of methods on an interface is decided by the consistency and cohesion of the abstraction it expresses, not how cumbersome it would be to implement it. Anyway, thanks for your answers Apo.
eljenso
+1  A: 

A great example of how interfaces are used is in the Collections framework. If you write a function that takes a List, then it doesn't matter if the user passes in a Vector or an ArrayList or a HashList or whatever. And you can pass that List to any function requiring a Collection or Iterable interface too.

This makes functions like Collections.sort(List list) possible, regardless of how the List is implemented.

Kip
A: 

Hello there,

Interfaces where a fetature added to java to allow multiple inheritance. The developers of Java though/realized that having multiple inheritance was a "dangerous" feature, that is why the came up with the idea of an interface.

multiple inheritance is dangerous because you might have a class like the following:


class Box{
    public int getSize(){
       return 0;
    }
    public int getArea(){
       return 1;
    }

}

class Triangle{
    public int getSize(){
       return 1;
    }
    public int getArea(){
       return 0;
    }

}

class FunckyFigure extends Box, Triable{
   // we do not implement the methods we will used the inherited ones
}

Which would be the method that should be called when we use


   FunckyFigure.GetArea(); 

All the problems are solved with interfaces, because you do know you can extend the interfaces and that they wont have classing methods... ofcourse the compiler is nice and tells you if you did not implemented a methods, but I like to think that is a side effect of a more interesting idea.

mandel
You might want to make a difference between multiple implementation inheritance and multiple interface inheritance in your answer, otherwise it gets confusing.
eljenso
+1  A: 

Interfaces allow statically typed languages to support polymorphism. An Object Oriented purist would insist that a language should provide inheritance, encapsulation, modularity and polymorphism in order to be a fully-featured Object Oriented language. In dynamically-typed - or duck typed - languages (like Smalltalk,) polymorphism is trivial; however, in statically typed languages (like Java or C#,) polymorphism is far from trivial (in fact, on the surface it seems to be at odds with the notion of strong typing.)

Let me demonstrate:

In a dynamically-typed (or duck typed) language (like Smalltalk), all variables are references to objects (nothing less and nothing more.) So, in Smalltalk, I can do this:

|anAnimal|    
anAnimal := Pig new.
anAnimal makeNoise.

anAnimal := Cow new.
anAnimal makeNoise.

That code:

  1. Declares a local variable called anAnimal (note that we DO NOT specify the TYPE of the variable - all variables are references to an object, no more and no less.)
  2. Creates a new instance of the class named "Pig"
  3. Assigns that new instance of Pig to the variable anAnimal.
  4. Sends the message makeNoise to the pig.
  5. Repeats the whole thing using a cow, but assigning it to the same exact variable as the Pig.

The same Java code would look something like this (making the assumption that Duck and Cow are subclasses of Animal:

Animal anAnimal = new Pig();
duck.makeNoise();

anAnimal = new Cow();
cow.makeNoise();

That's all well and good, until we introduce class Vegetable. Vegetables have some of the same behavior as Animal, but not all. For example, both Animal and Vegetable might be able to grow, but clearly vegetables don't make noise and animals cannot be harvested.

In Smalltalk, we can write this:

|aFarmObject|
aFarmObject := Cow new.
aFarmObject grow.
aFarmObject makeNoise.

aFarmObject := Corn new.
aFarmObject grow.
aFarmObject harvest.

This works perfectly well in Smalltalk because it is duck-typed (if it walks like a duck, and quacks like a duck - it is a duck.) In this case, when a message is sent to an object, a lookup is performed on the receiver's method list, and if a matching method is found, it is called. If not, some kind of NoSuchMethodError exception is thrown - but it's all done at runtime.

But in Java, a statically typed language, what type can we assign to our variable? Corn needs to inherit from Vegetable, to support grow, but cannot inherit from Animal, because it does not make noise. Cow needs to inherit from Animal to support makeNoise, but cannot inherit from Vegetable because it should not implement harvest. It looks like we need multiple inheritance - the ability to inherit from more than one class. But that turns out to be a pretty difficult language feature because of all the edge cases that pop up (what happens when more than one parallel superclass implement the same method?, etc.)

Along come interfaces...

If we make Animal and Vegetable classes, with each implementing Growable, we can declare that our Cow is Animal and our Corn is Vegetable. We can also declare that both Animal and Vegetable are Growable. That lets us write this to grow everything:

List<Growable> list = new ArrayList<Growable>();
list.add(new Cow());
list.add(new Corn());
list.add(new Pig());

for(Growable g : list) {
   g.grow();
}

And it lets us do this, to make animal noises:

List<Animal> list = new ArrayList<Animal>();
list.add(new Cow());
list.add(new Pig());
for(Animal a : list) {
  a.makeNoise();
}

The advantage to the duck-typed language is that you get really nice polymorphism: all a class has to do to provide behavior is provide the method. As long as everyone plays nice, and only sends messages that match defined methods, all is good. The downside is that the kind of error below isn't caught until runtime:

|aFarmObject|
aFarmObject := Corn new.
aFarmObject makeNoise. // No compiler error - not checked until runtime.

Statically-typed languages provide much better "programming by contract," because they will catch the two kinds of error below at compile-time:

// Compiler error: Corn cannot be cast to Animal.
Animal farmObject = new Corn();  
farmObject makeNoise();

--

// Compiler error: Animal doesn't have the harvest message.
Animal farmObject = new Cow();
farmObject.harvest();

So....to summarize:

  1. Interface implementation allows you to specify what kinds of things objects can do (interaction) and Class inheritance lets you specify how things should be done (implementation).

  2. Interfaces give us many of the benefits of "true" polymorphism, without sacrificing compiler type checking.

Jared
This is the text of my answer to another question: http://stackoverflow.com/questions/379282/why-the-use-of-both-a-base-class-and-an-interface-in-polymorphism/379491#379491. But, they're related answers.
Jared
So may I ask, how does a duck typed language distinguish between Animal.water() (which, the prudish farmer used to say that it takes a leak) and Plant.water() which he uses to water plants. Ambiguity is the enemy. Any amount of verbosity necessary to overcome ambiguity is acceptable IMO.
Bill K
Yep..ambiguity is the name of the game with duck typed languages. When working professionally in a duck typed language, it's not uncommon to see members (methods and variables) with names that are 50-100 characters in length.
Jared
Another big downside of duck typed languages is the inability to do programmatic refactoring based on static analysis - try asking a Smalltalk image for the list of all callers of your printString method...you will get the list of all callers of ALL printString methods....
Jared
...because the caller of Automobile#printString cannot be programmatically differentiated from the caller of NearEarthOrbit#printString.
Jared
I guess I'm glad both options exist. I like the reliability of stamping an interface on something to say "THIS IS A DUCK", but I can see how it's quite unnecessary (and even harmful) on smaller projects with smaller teams.
Bill K
You are confusing strongly typed with statically typed, and weakly typed with dynamically typed.
eljenso
According to wikipedia, the terms "strongly typed" and "weakly typed" are very versatile - and have been used in this way in the past. However; statically typed and dynamically typed are much more precise. I've edited the response to use that terminology instead. Thanks.
Jared
+2  A: 

This is the reason why Factory Patterns and other creational patterns are so popular in Java. You are correct that without them Java doesn't provide an out of the box mechanism for easy abstraction of instantiation. Still, you get abstraction everywhere where you don't create an object in your method, which should be most of your code.

As an aside, I generally encourage people to not follow the "IRealname" mechanism for naming interfaces. That's a Windows/COM thing that puts one foot in the grave of Hungarian notation and really isn't necessary (Java is already strongly typed, and the whole point of having interfaces is to have them as largely indistinguishable from class types as possible).

Christopher Smith
You are confusing strong typing with static typing.
eljenso
+2  A: 

I think you understand everything Interfaces do, but you're not yet imagining the situations in which an Interface is useful.

If you're instantiating, using and releasing an object all within a narrow scope (for example, within one method call), an Interface doesn't really add anything. Like you noted, the concrete class is known.

Where Interfaces are useful is when an object needs to be created one place and returned to a caller that may not care about the implementation details. Let's change your IBox example to an Shape. Now we can have implementations of Shape such as Rectangle, Circle, Triangle, etc., The implementations of the getArea() and getSize() methods will be completely different for each concrete class.

Now you can use a factory with a variety of createShape(params) methods which will return an appropriate Shape depending on the params passed in. Obviously, the factory will know about what type of Shape is being created, but the caller won't have to care about whether it's a circle, or a square, or so on.

Now, imagine you have a variety of operations you have to perform on your shapes. Maybe you need to sort them by area, set them all to a new size, and then display them in a UI. The Shapes are all created by the factory and then can be passed to the Sorter, Sizer and Display classes very easily. If you need to add a hexagon class some time in the future, you don't have to change anything but the factory. Without the Interface, adding another shape becomes a very messy process.

Ickster
+5  A: 

What makes interfaces useful is not the fact that "you can change your mind and use a different implementation later and only have to change the one place where the object is created". That's a non-issue.

The real point is already in the name: they define an interface that anyone at all can implement to use all code that operates on that interface. The best example is java.util.Collections which provides all kinds of useful methods that operate exclusively on interfaces, such as sort() or reverse() for List. The point here is that this code can now be used to sort or reverse any class that implements the List interfaces - not just ArrayList and LinkedList, but also classes that you write yourself, which may be implemented in a way the people who wrote java.util.Collections never imagined.

In the same way, you can write code that operates on well-known interfaces, or interfaces you define, and other people can use your code without having to ask you to support their classes.

Another common use of interfaces is for Callbacks. For example, java.swing.table.TableCellRenderer, which allows you to influence how a Swing table displays the data in a certain column. You implement that interface, pass an instance to the JTable, and at some point during the rendering of the table, your code will get called to do its stuff.

Michael Borgwardt
+1  A: 

Don't forget that at a later date you can take an existing class, and make it implement IBox, and it will then become available to all your box-aware code.

This becomes a bit clearer if interfaces are named -able. e.g.

public interface Saveable {
....

public interface Printable {
....

etc. (Naming schemes don't always work e.g. I'm not sure Boxable is appropriate here)

Brian Agnew
+1  A: 

The purpose of interfaces is abstraction, or decoupling from implementation.

If you introduce an abstraction in your program, you don't care about the possible implementations. You are interested in what it can do and not how, and you use an interface to express this in Java.

eljenso
The purpose of all structured programming is abstraction. Why would you say that the purpose of interfaces is abstraction, since I can achieve the exact same thing using generics and class composition?
Apocalisp
If all structured programming is abstraction (your claim), then interfaces are abstractions in that abstraction.
eljenso