159

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?

Raedwald
  • 40,290
  • 35
  • 127
  • 207
Click Upvote
  • 235,452
  • 251
  • 553
  • 736
  • 2
    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. – Herms Feb 02 '09 at 21:19
  • 2
    Technically, all strongly-typed OOP languages have them in some form or another. Untyped, or duck typed, languages don't have a similar concept. – Jared Feb 02 '09 at 21:24
  • 1
    @Jared Aren't you confusing strong typing with static typing, and "untyped" with dynamically typed? – eljenso Feb 04 '09 at 10:47
  • Polymorphism can be accomplished via interfaces also. Check the last section of this page http://codenuggets.com/2014/06/20/java-interface/ – Jeff Jul 01 '14 at 04:32
  • http://stackoverflow.com/a/24436493/1286942 – Jo Smo Jul 27 '15 at 03:27
  • What do you mean by "correct methods"? – Raedwald Jun 21 '16 at 07:13

17 Answers17

143

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
  • 24,113
  • 35
  • 128
  • 186
  • 54
    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. – Rogério Oct 13 '10 at 20:04
  • 16
    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. – trevorkavanaugh May 28 '14 at 21:31
  • 2
    This has very little to do with explaining interfaces and everything to do with the basics of polymorphism – A-Developer-Has-No-Name Dec 04 '16 at 19:59
124

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
  • 327,225
  • 74
  • 458
  • 699
  • 9
    That's a pretty good answer ,I like it when you gave examples from java package classes... – Owais Qureshi Dec 01 '13 at 21:04
  • 1
    I liked `you can write code that operates on well-known interfaces, or interfaces you define` – Manish Kumar Feb 08 '14 at 05:24
  • 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 Oct 31 '14 at 11:09
  • 4
    @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]. – Michael Borgwardt Oct 31 '14 at 12:02
  • @MichaelBorgwardt That sounds way better. :) Thanks for clarifying! – Powerslave Oct 31 '14 at 12:26
120

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 { }
peevesy
  • 1,309
  • 1
  • 8
  • 7
  • 6
    @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. – Powerslave Oct 31 '14 at 11:13
  • 6
    @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. – Madmenyo Nov 12 '14 at 19:00
  • Superb.. Explained very well. Thank you..! – Gurusinghe Sep 02 '15 at 00:32
  • 1
    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. – Alex G Apr 28 '16 at 00:50
  • @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 ! – peevesy Jun 21 '16 at 08:13
  • 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.. – BaSsGaz Aug 25 '17 at 17:48
48

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
  • 33,619
  • 8
  • 100
  • 150
  • 8
    Why is the purpose of interfaces polymorphism, if I can already achieve that in Java with subclassing and method overriding? – eljenso Feb 04 '09 at 11:13
  • 1
    It's the same thing, except that interfaces must omit any implementation. Classes can therefore implement more than one interface. – Apocalisp Feb 04 '09 at 14:25
  • 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 Feb 04 '09 at 14:49
  • 4
    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 Feb 04 '09 at 17:55
  • 1
    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 Feb 04 '09 at 18:39
  • 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 Feb 04 '09 at 20:24
  • 1
    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 Feb 04 '09 at 22:00
33

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
  • 23,116
  • 19
  • 76
  • 105
  • 2
    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 Feb 02 '09 at 21:31
  • 2
    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 Feb 02 '09 at 22:11
  • 1
    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 Feb 02 '09 at 22:17
  • 1
    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 Feb 02 '09 at 22:19
  • ...because the caller of Automobile#printString cannot be programmatically differentiated from the caller of NearEarthOrbit#printString. – Jared Feb 02 '09 at 22:20
  • 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 Feb 03 '09 at 02:54
  • You are confusing strongly typed with statically typed, and weakly typed with dynamically typed. – eljenso Feb 04 '09 at 11:06
  • 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 Feb 04 '09 at 15:22
  • You should have made the pig fly... much funner. – Edward J Beckett Mar 01 '15 at 01:30
9

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.

Community
  • 1
  • 1
Johannes Weiss
  • 47,880
  • 15
  • 95
  • 129
6

WHY INTERFACE??????

It starts with a dog. In particular, a pug.

The pug has various behaviors:

public class Pug { 
private String name;
public Pug(String n) { name = n; } 
public String getName() { return name; }  
public String bark() { return  "Arf!"; } 
public boolean hasCurlyTail() { return true; } }

And you have a Labrador, who also has a set of behaviors.

public class Lab { 
private String name; 
public Lab(String n) { name = n; } 
public String getName() { return name; } 
public String bark() { return "Woof!"; } 
public boolean hasCurlyTail() { return false; } }

We can make some pugs and labs:

Pug pug = new Pug("Spot"); 
Lab lab = new Lab("Fido");

And we can invoke their behaviors:

pug.bark() -> "Arf!" 
lab.bark() -> "Woof!" 
pug.hasCurlyTail() -> true 
lab.hasCurlyTail() -> false 
pug.getName() -> "Spot"

Let's say I run a dog kennel and I need to keep track of all the dogs I'm housing. I need to store my pugs and labradors in separate arrays:

public class Kennel { 
Pug[] pugs = new Pug[10]; 
Lab[] labs = new Lab[10];  
public void addPug(Pug p) { ... } 
public void addLab(Lab l) { ... } 
public void printDogs() { // Display names of all the dogs } }

But this is clearly not optimal. If I want to house some poodles, too, I have to change my Kennel definition to add an array of Poodles. In fact, I need a separate array for each kind of dog.

Insight: both pugs and labradors (and poodles) are types of dogs and they have the same set of behaviors. That is, we can say (for the purposes of this example) that all dogs can bark, have a name, and may or may not have a curly tail. We can use an interface to define what all dogs can do, but leave it up to the specific types of dogs to implement those particular behaviors. The interface says "here are the things that all dogs can do" but doesn't say how each behavior is done.

public interface Dog 
{
public String bark(); 
public String getName(); 
public boolean hasCurlyTail(); }

Then I slightly alter the Pug and Lab classes to implement the Dog behaviors. We can say that a Pug is a Dog and a Lab is a dog.

public class Pug implements Dog {
// the rest is the same as before } 

public class Lab implements Dog { 
// the rest is the same as before 
}

I can still instantiate Pugs and Labs as I previously did, but now I also get a new way to do it:

Dog d1 = new Pug("Spot"); 
Dog d2 = new Lab("Fido");

This says that d1 is not only a Dog, it's specifically a Pug. And d2 is also a Dog, specifically a Lab. We can invoke the behaviors and they work as before:

d1.bark() -> "Arf!" 
d2.bark() -> "Woof!" 
d1.hasCurlyTail() -> true 
d2.hasCurlyTail() -> false 
d1.getName() -> "Spot"

Here's where all the extra work pays off. The Kennel class become much simpler. I need only one array and one addDog method. Both will work with any object that is a dog; that is, objects that implement the Dog interface.

public class Kennel {
Dog[] dogs = new Dog[20]; 
public void addDog(Dog d) { ... } 
public void printDogs() {
// Display names of all the dogs } }

Here's how to use it:

Kennel k = new Kennel(); 
Dog d1 = new Pug("Spot"); 
Dog d2 = new Lab("Fido"); 
k.addDog(d1); 
k.addDog(d2); 
k.printDogs();

The last statement would display: Spot Fido

An interface give you the ability to specify a set of behaviors that all classes that implement the interface will share in common. Consequently, we can define variables and collections (such as arrays) that don't have to know in advance what kind of specific object they will hold, only that they'll hold objects that implement the interface.

6

you could do

Ibox myBox = new Rectangle();

that way you are using this object as Ibox and you don't care that its really Rectangle .

shivtej
  • 183
  • 5
  • 17
IAdapter
  • 55,820
  • 69
  • 166
  • 236
  • That means we could write like this?! > Rectangle inst = new Rectangle (); – Dr.jacky Apr 17 '16 at 04:15
  • @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. – Kolob Canyon Jun 06 '18 at 17:00
6

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
  • 2,111
  • 4
  • 22
  • 42
3

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?

I am updating the answer with new features of interface, which have introduced with java 8 version.

From oracle documentation page on summary of interface :

An interface declaration can contain

  1. method signatures
  2. default methods
  3. static methods
  4. constant definitions.

The only methods that have implementations are default and static methods.

Uses of interface:

  1. To define a contract
  2. To link unrelated classes with has a capabilities (e.g. classes implementing Serializable interface may or may not have any relation between them except implementing that interface
  3. To provide interchangeable implementation e.g. strategy pattern
  4. Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces
  5. Organize helper methods in your libraries with static methods ( you can keep static methods specific to an interface in the same interface rather than in a separate class)

Some related SE questions with respect to difference between abstract class and interface and use cases with working examples:

What is the difference between an interface and abstract class?

How should I have explained the difference between an Interface and an Abstract class?

Have a look at documentation page to understand new features added in java 8 : default methods and static methods.

Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
  • 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. – Tagir Valeev Mar 07 '16 at 15:35
3

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
  • 99,109
  • 82
  • 222
  • 258
3

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
  • 4,947
  • 1
  • 30
  • 18
3

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
  • 254,044
  • 36
  • 316
  • 423
2

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
  • 15,950
  • 6
  • 53
  • 62
  • 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 Feb 04 '09 at 18:08
  • 1
    If all structured programming is abstraction (your claim), then interfaces are abstractions in that abstraction. – eljenso Feb 04 '09 at 18:15
1

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
  • 17,208
  • 8
  • 27
  • 35
1

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
  • 2,807
  • 2
  • 21
  • 25
  • You might want to make a difference between multiple implementation inheritance and multiple interface inheritance in your answer, otherwise it gets confusing. – eljenso Feb 04 '09 at 11:03
0

Here is my understanding of interface advantage. Correct me if I am wrong. Imagine we are developing OS and other team is developing the drivers for some devices. So we have developed an interface StorageDevice. We have two implementations of it (FDD and HDD) provided by other developers team.

Then we have a OperatingSystem class which can call interface methods such as saveData by just passing an instance of class implemented the StorageDevice interface.

The advantage here is that we don't care about the implementation of the interface. The other team will do the job by implementing the StorageDevice interface.

package mypack;

interface StorageDevice {
    void saveData (String data);
}


class FDD implements StorageDevice {
    public void saveData (String data) {
        System.out.println("Save to floppy drive! Data: "+data);
    }
}

class HDD implements StorageDevice {
    public void saveData (String data) {
        System.out.println("Save to hard disk drive! Data: "+data);
    }
}

class OperatingSystem {
    public String name;
    StorageDevice[] devices;
    public OperatingSystem(String name, StorageDevice[] devices) {

        this.name = name;
        this.devices = devices.clone();

        System.out.println("Running OS " + this.name);
        System.out.println("List with storage devices available:");
        for (StorageDevice s: devices) {
            System.out.println(s);
        }

    }

    public void saveSomeDataToStorageDevice (StorageDevice storage, String data) {
        storage.saveData(data);
    }
}

public class Main {

    public static void main(String[] args) {

        StorageDevice fdd0 = new FDD();
        StorageDevice hdd0 = new HDD();     
        StorageDevice[] devs = {fdd0, hdd0};        
        OperatingSystem os = new OperatingSystem("Linux", devs);
        os.saveSomeDataToStorageDevice(fdd0, "blah, blah, blah...");    
    }
}
  • 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. – Vladimir Georgiev Jun 22 '18 at 08:19