Is there more to an interface than having the correct methods
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:
- 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.)
- Creates a new instance of the class named "Pig"
- Assigns that new instance of Pig to the variable anAnimal.
- Sends the message
makeNoise
to the pig. - 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:
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).
Interfaces give us many of the benefits of "true" polymorphism, without sacrificing compiler type checking.
Related videos on Youtube
![gregory boero.teyssier](https://lh5.googleusercontent.com/-BO8W53p9a00/AAAAAAAAAAI/AAAAAAAABp0/NZ9NqjQPDiE/photo.jpg?sz=256)
Comments
-
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 over 15 yearsRemember, 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 over 15 yearsTechnically, all strongly-typed OOP languages have them in some form or another. Untyped, or duck typed, languages don't have a similar concept.
-
eljenso over 15 years@Jared Aren't you confusing strong typing with static typing, and "untyped" with dynamically typed?
-
Jeff about 10 yearsPolymorphism can be accomplished via interfaces also. Check the last section of this page codenuggets.com/2014/06/20/java-interface
-
Jo Smo almost 9 years
-
Raedwald about 8 yearsWhat do you mean by "correct methods"?
-
-
gregory boero.teyssier over 15 yearsIs 'List' supposed to be an interface member?
-
rmeador over 15 yearsList is an interface in the java collections library.
-
palantus over 15 yearsList 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 over 15 yearsThis is the text of my answer to another question: stackoverflow.com/questions/379282/…. But, they're related answers.
-
Jared over 15 yearsYep..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 over 15 yearsAnother 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 over 15 years...because the caller of Automobile#printString cannot be programmatically differentiated from the caller of NearEarthOrbit#printString.
-
Bill K over 15 yearsI 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 over 15 yearsYou might want to make a difference between multiple implementation inheritance and multiple interface inheritance in your answer, otherwise it gets confusing.
-
eljenso over 15 yearsYou are confusing strongly typed with statically typed, and weakly typed with dynamically typed.
-
eljenso over 15 yearsYou are confusing strong typing with static typing.
-
eljenso over 15 yearsWhy is the purpose of interfaces polymorphism, if I can already achieve that in Java with subclassing and method overriding?
-
Apocalisp over 15 yearsIt's the same thing, except that interfaces must omit any implementation. Classes can therefore implement more than one interface.
-
eljenso over 15 yearsI 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 over 15 yearsAccording 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 over 15 yearsHey, 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 over 15 yearsThe 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 over 15 yearsIf all structured programming is abstraction (your claim), then interfaces are abstractions in that abstraction.
-
eljenso over 15 yearsI 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 over 15 yearsWe 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 over 13 yearsThere 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 over 10 yearsThat's a pretty good answer ,I like it when you gave examples from java package classes...
-
Manish Kumar over 10 yearsI liked
you can write code that operates on well-known interfaces, or interfaces you define
-
trevorkavanaugh about 10 yearsHow 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 over 9 yearsWait 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 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 interfacePredator
would be more appropriate here. -
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 over 9 years@MichaelBorgwardt That sounds way better. :) Thanks for clarifying!
-
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 over 9 yearsYou should have made the pig fly... much funner.
-
Gurusinghe almost 9 yearsSuperb.. Explained very well. Thank you..!
-
Tagir Valeev over 8 yearsI 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 about 8 yearsThat means we could write like this?! > Rectangle inst = new Rectangle ();
-
Alex G about 8 yearsI 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 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 over 7 yearsThis has very little to do with explaining interfaces and everything to do with the basics of polymorphism
-
BaSsGaz almost 7 yearsBut still,
Chewable
could be an class extending fromAnimal
, andBird
extends from it. Would be better since you could give thechew()
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 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 thatSquare
andRectangle
have the same methods... this can result in a nightmare when you have a larger code base... Remember, interfaces define a template. -
Vladimir Georgiev about 6 yearssame 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 about 5 years@niranjan kurambhatti i can make all classes to extend dog but still why interface??