43

Let's say we have two classes, Tiger and Aeroplane. One thing in common for these two types is the Speed. I know that it would be illogical to create a superclass ClassWithSpeed and then derive subclasses Aeroplane and Tiger from it. Instead, it is better to create an interface that contains the method speed() and then implement it in Aeroplane and Tiger. I get that. But, we can do the same thing without interfaces. We could define method speed() in Aeroplane and method speed() in Tiger. The only (maybe very big) flaw it would be that we couldn't "reach" the objects of Tiger and Aeroplane through an interface reference.

I am beginner in Java and OOP, and I would be very grateful if someone explained to me the role of interfaces. Cheers!

Want
  • 820
  • 2
  • 9
  • 20
  • 21
    It sounds like you have already identified a pretty important "flaw"... – Oliver Charlesworth May 26 '13 at 16:12
  • 1
    You can have a method `getCurrentSpeed(InterfaceWithSpeed)` and call it `getCurrentSpeed(new Aeroplane())` or `getCurrentSpeed(new Tiger())`. – Luiggi Mendoza May 26 '13 at 16:12
  • 6
    This question is most likely relevant to programmers.stackoverflow.com. – Ryan Ransford May 26 '13 at 16:13
  • 5
    You have correctly figured out why we have interfaces. Can you make more clear what exactly is the question? – Theodoros Chatzigiannakis May 26 '13 at 16:29
  • 1
    I would use a common interface when objects can logically be treated in the same manner. I wouldn't consider an aeroplane and a tiger comparable in this manner, for instance, would you compare the airspeed or landspeed? – oɔɯǝɹ May 26 '13 at 18:29
  • Two words - Dynamic polymorphism. – mihirjoshi May 26 '13 at 19:05
  • 6
    @RyanRansford the correct link is http://programmers.stackexchange.com/. –  May 26 '13 at 22:11
  • I would like to point that, Interfaces are something which adds a behavior to your object. SO it is perfectly fine to create an Interface with some name and have a method speed() in it. – dharam May 27 '13 at 02:34
  • Interface is just to use it to get this method. With interfaces you can do something like this: getSpeed(HasSpeed hs)...and pass both tigers or airplanes. That is it, Interfaces are contracts where you say that you will put those methods declared in the interface in the classes that implement it. – Leandro Lima May 27 '13 at 05:42
  • I have seen interfaces used far more for abstract stuff (like collections of objects) than real stuff ( like movable physical objects). http://stackoverflow.com/questions/8896575/what-does-this-statement . – Jesvin Jose May 27 '13 at 11:17
  • Be aware: interfaces in Java are not merely a declaration of structure (their meaning don't reduce to "a set of methods with these names and signatures") but also of semantics. See http://stackoverflow.com/questions/5691449/why-interfaces-must-be-declared-in-java – leonbloy Jun 03 '13 at 04:06

12 Answers12

74

It's:

public int howFast(Airplane airplane) {
    return airplane.speed();
}

public int howFast(Tiger tiger) {
    return tiger.speed();
}

public int howFast(Rocket rocket) {
    return rocket.speed();
}

public int howFast(ThingThatHasntBeenInventedYet thingx) {
    // wait... what? HOW IS THIS POSSIBLE?!
    return thingx.speed();
}

...

vs

public int howFast(Mover mover) {
    return mover.speed();
}

Now, imagine having to go back and change all those howFast functions in the future.

Interface or no, each class will have to implement or inherit the speed() method. An interface lets you use those disparate classes more easily, because they've each promised to behave in a certain way. You'll call speed(), and they'll return an int, so you don't have to write separate methods for every possible class.

When you find you need to handle speed differently because of a breakthrough in relativistic physics, you only need to update the methods that call speed(). When your great-granddaughter writes a class for HyperIntelligentMonkeyFish, she doesn't have to disassemble your ancient binary and make changes so that your code can monitor and control her mutant army. She needs only declare that HyperIntelligentMonkeyFish implements Mover.

maybeWeCouldStealAVan
  • 15,492
  • 2
  • 23
  • 32
  • 8
    +1 - "Mover" is such a better name than my "IObjectWithSpeed", and your code is nicely illustrative. – Andy Thomas May 26 '13 at 16:22
  • 4
    An interface doesn't provide implementations so you'd still have to change the speed functions individually... – anana May 26 '13 at 16:32
  • @anana Yep, I meant the `howFast` consumers of the speed functions. Edited. – maybeWeCouldStealAVan May 26 '13 at 16:39
  • 1
    Refer to the 'Strategy Pattern' to take this example a step further; where Tiger may use a PodalMoverStrategy and Aeroplane may use an AirborneMechanizedMoverStrategy – JustinC May 26 '13 at 19:15
  • 1
    HyperIntelligentMonkeyFish. And a great-granddaughter. What a pretty example. – Franz May 26 '13 at 23:01
  • 1
    If my granddaughter still has to write Java, I think we'll have bigger problems than OOP or interfaces... – TC1 May 27 '13 at 08:59
  • 2
    Should maybe be said that you should probably only add interfaces when there's a need and they make sense. Don't make interfaces for all methods just in case :p – Svish May 27 '13 at 09:22
8

Interfaces allow Java, since it is statically typed, to work around multiple inheritance limitations to the degree felt worthwhile by the language designers.

In a dynamic language (like Python, Ruby, etc.) you can just call the speed method on any arbitrary object and discover at runtime if it is there or not.

Java, on the other hand, is statically typed, which means the compiler has to agree that the method will be there ahead of time. The only way to do that on classes that don't share common ancestry, and may only have Object in common, is an interface.

Since objects can implement an arbitrary number of interfaces, this means you get the goodness of multiple inheritance (a single object that can pose as multiple different objects for different methods) without the downside (of conflicting implementations in the two super classes).

With Java 8, the designers of the language concluded that interfaces without any implementation was overly restrictive (they didn't like my solution I guess ;-)), so they allow for a default implementation, thus expanding the multi-inheritance options of interfaces, while still trying to avoid the conflicting implementation problem via a complex set of precedence rules so that there is an unambiguous default implementation to execute.

Community
  • 1
  • 1
Yishai
  • 90,445
  • 31
  • 189
  • 263
  • Re. the multiple inheritance bit, can you update this to address Java 8's new interface default implementations and the fail-fast approach associated with same? – nanofarad Dec 31 '13 at 17:40
6

I am trying to explain the advantage of interface with the following example-

suppose you have another class where you need to use the tiger or AeroPlane as parameter. So by using interface you can call using

someObject.someMethod(ClassWithSpeed)

but if you dont use interface you can use

someObject.someMethod(Tiger)
someObject.someMethod(AeroPlane)

Now what should you do? Your probable answer will be like, "I will use two overloaded method".

This is okay so far, But

Say you need to add more options (say car, cycle, rabbit, tortoise.... 100 others). So what will you do to make the change of your existing code?? you will need to change a lots of things..

The overall example above has only one purpose. That is to say

"we need interface to create a better, reusable and properly object oriented design"

N.B.

  1. if you are sure the program is too small and you will never need to change them then I think it is okay to implement without interface
stinepike
  • 54,068
  • 14
  • 92
  • 112
  • So, the only advantage is that we could have interface reference that can refer to various objects that implement that interface? – Want May 26 '13 at 16:23
  • Overall the main advantages are,, portability, reusability – stinepike May 26 '13 at 16:24
  • 3
    You'd still need to make the change in every class if you use an interface, the interface doesn't provide an implementation... – anana May 26 '13 at 16:55
  • @anana.. yup .. instead of advantage of interface I added super class's :D.. was just editing again.. thanks for pointing out – stinepike May 26 '13 at 16:57
5

Defining an interface allows you to define methods that work not only on Aeroplane and Tiger, but also other classes that share the same interface.

For example, say your interface is IObjectWithSpeed. Then you can define a method like this -- in a single class that operates on IObjectWithSpeed objects.

  public double calculateSecondsToTravel( IObjectWithSpeed obj, double distance ) {
       return distance / obj.getSpeed();
  }

Interfaces allow us to satisfy the open/closed principle - open for extension, but closed for modification. The single implementation of the method above doesn't need to be modified as new classes are defined that implement IObjectWithSpeed.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • 2
    Yes, but we could implement speed() in every class. We don't save time nor space, because in the interface we don't define the function. – Want May 26 '13 at 16:15
  • BUT with an interface you could define speed() in ONE class -- i.e., a class that does not implement IObjectWithSpeed. – Andy Thomas May 26 '13 at 16:18
3

Aside from being descriptive for those classes' functionality, methods of an interface could be used without any knowledge about the classes implementing it, even for classes that were not yet defined.

So for example, if you'd need a class Transport that computes say efficient routes, it could be given a class that implements ClassWithSpeed as a parameter and use its method speed() for computing what it needs. This way you could use it with our class Aeroplane, but also with any class we define later, say Boat. Java will take care that if you want to use a class as a parameter to Transport it will implement ClassWithSpeed, and that any class implementing ClassWithSpeed implements the method speed() so that it can be used.

anana
  • 1,461
  • 10
  • 11
3

I want go into much theoretical details but will try to explain using this example.

Consider JDBC API. It is API used to deal with database related options in the Java. Now, there are so many databases in the industry. How would one write drivers for that? Well, the quick and dirty approach may be write own implementation using our own classes and API.

But think from the programmer's perspective. Will they start learning DATABASE DRIVER's API while using different database? The answer is NO.

So what is the solution to the problem ? Just have a well defined API which anyone can extend for his own implementation.

In JDBC API, there are some Interfaces which are Connection, ResultSet, PreparedStatement, Statement etc. Now each database vendor will implement the interface and will write his own implementation for that. Result ? : Reduced effort from the developer and easy understandability.

Now, what this custom implementation might consisting of ? It's simple. They do what, take ResultSet interface for example and implement it and in whatever method the ResultSet is gettting returned, return THE CLASS THAT IMPLEMENTS ResultSet interface like this

ResultSet rs=new ResultSetImpl(); //this is what they are doing internally.

So interface are like contracts. They define what your class is able to do and they give your application flexibility. You can create your own APIs using interfaces properly.

Hope this helps you.

ATR
  • 2,160
  • 4
  • 22
  • 43
3

An interface is not simply a method signature.

It is a type that represents a contract. The contract is the thing, not the method signatures. When a class implements an interface, it is because there is a contract for a shared behavior that the class has an interest in implementing as a type. That contract is implemented via the specified members which are usually method bodies but may also include static final fields.

It may be true that a tiger and an aeroplane both could be expressed as a type with a common behavior implemented through speed() ... and if so, then the interface represents the contract for expressing that behavior.

scottb
  • 9,908
  • 3
  • 40
  • 56
1

The interface (as a language construct) is used by the compiler to prove that the method call is valid and allows you to have dependent classes interact with the implementing class while having the least possible knowledge about the implementing class.

Ryan Ransford
  • 3,224
  • 28
  • 35
1

This is a very wide question to give a simple answer. I can recommend a book Interface Oriented Design: With Patterns. It explains all power of interfaces. And why we should not avoid them.

Mikhail
  • 4,175
  • 15
  • 31
1

On language level, the only use of interfaces is, like you mentioned, to be able to refer to different classes in a common way. On people level, however, the picture looks different: IMO Java is strong when used in big projects where the design and the implementation are done by separate people, often from separate companies. Now, instead of writing a specification on a Word document, the system architects can create a bunch of classes that implementers can then directly insert in their IDEs and start working on them. In other words it is more convenient instead of declaring that "Class X implements methods Y and Z in order for it to be used for purpose A, just to say that "Class X implements interface A"

Jencel
  • 722
  • 7
  • 17
1

Have you tried using composition instead?, if I want 2 dissimilar classes to inherit the same abilities I use a class which takes an object of the type its working with by using abstract classes and checking the instances. Interfaces are useful for forcing methods to be including in the class but don't require any implementation or for 2 teams of coders to work on different coding areas.

Class Tiger {
  public MovingEntity mover;

 public Tiger(){

  mover.speed=30;
  mover.directionX=-1;
  mover.move(mover);

 }

}
Class Plane {
  public MovingEntity mover;

 public Plane(){
  mover.speed=500;
  mover.directionX=-1;
  mover.move(mover);

 }


Abstract Class Moverable(){
  private int xPos;
  private int yPos;
  private int directionX;
  private int directionY;
  private int speed;


Class MovingEntity extends Moverable {
 public void move(Moverable m){
   if(m instanceof Tiger){

      xPos+=directionX*speed;
      yPos+=directionY*speed;

   }else if(m instanceof Plane){
      xPos+=directionX*speed;
      yPos+=directionY*speed;

   }
 }
David Ryan
  • 67
  • 2
  • 9
0

Because creating interface gives you Polymorphism, across all those classes i.e. Tiger and Aeroplane.

You can extend from an (abstract or concrete) class when the base class's functionality is going to be the core of your child class's functionality as well.

You use interfaces when you want to add an augmented functionality to your class in addition to its core functionality. So using interfaces would give you Polymorphism even when its not your class's core functionality (because you've entered a contract by implementing the interface). This is a huge advantage over creating a speed() method with each class.