Is there more to an interface than having the correct methods

168,058

Solution 1

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.

Solution 2

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.

Solution 3

One of the many uses I have read is where its difficult without multiple-inheritance-using-interfaces in Java :

class Animal
{
void walk() { } 
....
.... //other methods and finally
void chew() { } //concentrate on this
} 

Now, Imagine a case where:

class Reptile extends Animal 
{ 
//reptile specific code here
} //not a problem here

but,

class Bird extends Animal
{
...... //other Bird specific code
} //now Birds cannot chew so this would a problem in the sense Bird classes can also call chew() method which is unwanted

Better design would be:

class Animal
{
void walk() { } 
....
.... //other methods 
} 

Animal does not have the chew() method and instead is put in an interface as :

interface Chewable {
void chew();
}

and have Reptile class implement this and not Birds (since Birds cannot chew) :

class Reptile extends Animal implements Chewable { } 

and incase of Birds simply:

class Bird extends Animal { }

Solution 4

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.

Solution 5

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.

Share:
168,058

Related videos on Youtube

gregory boero.teyssier
Author by

gregory boero.teyssier

https://ali.actor

Updated on June 22, 2020

Comments

  • gregory boero.teyssier
    gregory boero.teyssier about 4 years

    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?

    • MarioRicalde
      MarioRicalde over 15 years
      Remember, interfaces aren't specific to Java. All OOP languages have them in some form or another, though not always as explicitly defined as Java.
    • Jared
      Jared over 15 years
      Technically, all strongly-typed OOP languages have them in some form or another. Untyped, or duck typed, languages don't have a similar concept.
    • eljenso
      eljenso over 15 years
      @Jared Aren't you confusing strong typing with static typing, and "untyped" with dynamically typed?
    • Jeff
      Jeff about 10 years
      Polymorphism can be accomplished via interfaces also. Check the last section of this page codenuggets.com/2014/06/20/java-interface
    • Jo Smo
      Jo Smo almost 9 years
    • Raedwald
      Raedwald about 8 years
      What do you mean by "correct methods"?
  • gregory boero.teyssier
    gregory boero.teyssier over 15 years
    Is 'List' supposed to be an interface member?
  • rmeador
    rmeador over 15 years
    List is an interface in the java collections library.
  • palantus
    palantus over 15 years
    List is an interface in the standard Java library (java.sun.com/javase/6/docs/api/java/util/List.html). He's just using it to illustrate his point.
  • Jared
    Jared over 15 years
    This is the text of my answer to another question: stackoverflow.com/questions/379282/…. But, they're related answers.
  • Jared
    Jared over 15 years
    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
    Jared over 15 years
    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
    Jared over 15 years
    ...because the caller of Automobile#printString cannot be programmatically differentiated from the caller of NearEarthOrbit#printString.
  • Bill K
    Bill K over 15 years
    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.
  • eljenso
    eljenso over 15 years
    You might want to make a difference between multiple implementation inheritance and multiple interface inheritance in your answer, otherwise it gets confusing.
  • eljenso
    eljenso over 15 years
    You are confusing strongly typed with statically typed, and weakly typed with dynamically typed.
  • eljenso
    eljenso over 15 years
    You are confusing strong typing with static typing.
  • eljenso
    eljenso over 15 years
    Why is the purpose of interfaces polymorphism, if I can already achieve that in Java with subclassing and method overriding?
  • Apocalisp
    Apocalisp over 15 years
    It's the same thing, except that interfaces must omit any implementation. Classes can therefore implement more than one interface.
  • eljenso
    eljenso over 15 years
    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.
  • Jared
    Jared over 15 years
    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.
  • Apocalisp
    Apocalisp over 15 years
    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
    Apocalisp over 15 years
    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?
  • eljenso
    eljenso over 15 years
    If all structured programming is abstraction (your claim), then interfaces are abstractions in that abstraction.
  • eljenso
    eljenso over 15 years
    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
    eljenso over 15 years
    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.
  • Rogério
    Rogério over 13 years
    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.
  • Owais Qureshi
    Owais Qureshi over 10 years
    That's a pretty good answer ,I like it when you gave examples from java package classes...
  • Manish Kumar
    Manish Kumar over 10 years
    I liked you can write code that operates on well-known interfaces, or interfaces you define
  • trevorkavanaugh
    trevorkavanaugh about 10 years
    How did this get selected as the answer? It's a brief description of why polymorphism is useful, but as the poster above said, I would expect a better explanation of multiple interfaces and even more importantly when it is appropriate to use an interface vs an abstract class.
  • Powerslave
    Powerslave over 9 years
    Wait a moment... What makes interfaces useful is not [the ability to use any implementation you like], but rather [the ability to use any implementation you like]? Mentioning the opposite case is pretty much a good point though.
  • Powerslave
    Powerslave over 9 years
    @CHEBURASHKA And bad naming. If Reptile "chews", than not itself is "chewable". The convention of (sometimes) naming interfaces Whateverable should only be applied where it makes perfect sense. Naming the interface Predator would be more appropriate here.
  • Michael Borgwardt
    Michael Borgwardt over 9 years
    @Powerslave:paraphrase it more like What makes interfaces useful is not [the ability to write code where you have to change only one line when changing the impementation] but rather [the ability to write code where you don't even specify an implementation at all].
  • Powerslave
    Powerslave over 9 years
    @MichaelBorgwardt That sounds way better. :) Thanks for clarifying!
  • Madmenyo
    Madmenyo over 9 years
    @Powerslave It's correct imho, a reptile is "able to chew"/"chewable". A hawk is a predator but still not able to chew... just nitpicking but "chewable" can be defined better in the documentation of the interface.
  • Edward J Beckett
    Edward J Beckett over 9 years
    You should have made the pig fly... much funner.
  • Gurusinghe
    Gurusinghe almost 9 years
    Superb.. Explained very well. Thank you..!
  • Tagir Valeev
    Tagir Valeev over 8 years
    I removed java-8 tag as the question did not ask anything about java-8 (and actually was asked long time before java-8). Tags are for questions, not for answers.
  • Dr.jacky
    Dr.jacky about 8 years
    That means we could write like this?! > Rectangle inst = new Rectangle ();
  • Alex G
    Alex G about 8 years
    I don't get it. All it seems like is that interfaces are a good way to make sure you implement the same methods in each class that implements it, (eg. so it prevents me from making the stupid choice of a Bird class with run() and a Dog class with runn() -- they're all the same). But by paying attention and making my classes have the same method formats/structures, couldn't I achieve this same thing? Really seems like interfaces just make sure the programmer isn't being forgetful. Also, interfaces don't seem to save me time; I still need to define the method in each class that implements it.
  • peevesy
    peevesy about 8 years
    @AlexG - i told one of the many uses dude :) There are more, we had barely scratched the surface to answer the question in a simple fashion !
  • YisraelU
    YisraelU over 7 years
    This has very little to do with explaining interfaces and everything to do with the basics of polymorphism
  • BaSsGaz
    BaSsGaz almost 7 years
    But still, Chewable could be an class extending from Animal, and Bird extends from it. Would be better since you could give the chew() a body so all sub-classes automatically know how to chew by default instead of repeating code, this is not the best example, but still..
  • Kellen Stuart
    Kellen Stuart about 6 years
    @Mr.Hyde If you later want to add Square you'd have a problem.... if you try to do it without interfaces, you cannot guarantee that Square and Rectangle have the same methods... this can result in a nightmare when you have a larger code base... Remember, interfaces define a template.
  • Vladimir Georgiev
    Vladimir Georgiev about 6 years
    same thing can be done with abstract class StorageDevice and FDD and HDD classes extending StorageDevice class. but if we use abstract class we cant take advantage of multiple inheritance.
  • Jeeva
    Jeeva about 5 years
    @niranjan kurambhatti i can make all classes to extend dog but still why interface??