views:

180

answers:

11

OK so I gather that Interfaces are a way to enforce that an object implements a certain amount of functionality, without having to use inheritance. Kind of like a contract. And I semi see the point of them.

But if all you have in the interface is:

 public interface animal{
  void eat(object food);
}

and it has no implementation as such, then whoever uses your interface has to write it from scratch, every time.

If you are creating a number of classes all implementing such features and the implementation is only slightly different, this is going to be a lot of hard work.

Any help to get my head around this is appreciated because I know it's really important.

+3  A: 

Prefer Composition over Inheritance. This way, you can implement (say) eat() in a class that gets incorporated into all your animals as a data member. Write it once, reuse it, but in a way that doesn't bind one kind of functionality explicitly to another.

If you had two (or ten) different ways of eating, you could swap them out as needed.

Carl Manaster
Although composition seems the best way to avoid code duplication in this particular case, this answer tends to make think that interfaces are useless in Java. Don't forget that there's also another design principle saying "program to interfaces, not concrete classes". So interfaces in Java are definitely something to understand and use almost everywhere.
Damien
Good point. I just edited to add the "swapping out" bit, which I think may address it. Thanks.
Carl Manaster
+1  A: 

Right, you need to implement it ever time but you can implement it differently every time and any class that calls it doesn't need to worry about how it's implemented.

For example, if you have a Zoo object with a bunch of animals (new Tiger(), Lion(), Bear()) then your zoo can do for each Animal a in some collection a.eat() and it will work. The zoo doesn't care that there are three different types of animals that eat in totally different ways.

+3  A: 

You are confusing interfaces and inheritance. They are different concepts and can complement to each other. If all the eat methods are only slightly different, then you can create a base class which will contain the common code and will be invoked from the subclasses through overriden methods which add the different parts. The base class can still implement the interface. Hope it is clear.

Petar Minchev
+1  A: 

and it has no implementation as such then whoever uses your interface has to write it from scratch..every time.

Each implementation of the interface can be different. The point is that you can use interface without knowing the implementation. Consider example:

public interface ILogger
{
    void WriteMessage(string message);
}

Your application may use ILogger interface for logging errors/debug information, etc. But it doesn't matter how logger is implemented - it can be FileSystemLogger, or DatabaseLogger, or any other implementation. So you will be able to substitute implementations at any time without changing all places in code where logging was mentioned.

Andrew Bezzub
+1  A: 

If you are creating a number of classes all implementing such features and the implementation is only slightly different, this is going to be a lot of hard work.

In that case you are easily allowed to create another layer in you hierarchy of classes which implements Animal but is an ancestor class for all animals that eat in some way, for example

class Herbivore implements Animal {
  public void eat(Object food) {
   ...
  }
}

class Cow extends Herbivore..
class Horse extends Herbivore..

and you are allowed to override eat by using super.eat() and changing only the slight part..

You should look forward code reuse and encapsulation of components at the same time.. then if your interface really doesn't characterize the class itself but just a component of it you can go by composition as suggested by Carl Manaster.

Jack
+2  A: 

You should think of an interface as an authoritative declaration of behaviour, which has nothing to do with implementation issues in the first place.

If you want to avoid code duplication, then you use an abstract base class in combination with the interface. Here you then can implement all the stuff that might be repeated in all interface-implementing classes otherwise.

HTH.
Thomas

Thomas Weller
A: 

You are thinking about it backwards. Instead of thinking about the implementation first, you think about behavior (as described by the method signature) first. Then you implement the behavior as appropriate in the base classes giving a much more flexible, extensible system. You dismissed "design by contract' pretty quickly, but it's a key design strategy and the basis for web services, SOA, etc.

Joe
+1  A: 

Using interfaces is more about giving the consuming code a way to know what you expect from it, rather than you needing to be concerned about the details of the consuming code.

For example, one of the ways we use interfaces a lot is in our Business Layer / Data Access Layer.

Because our business layer (BL) assembly will communicate with directly with the data access layer (DAL) assembly, the DAL cannot communicate directly with the BL. What happens if the DAL wants to use objects rather than individual fields? You would have to define your own DAL objects, and hydrate them with the input you've just received. Basically, a lot more work, more resources consumed, and multiple objects that represent the same data which makes for a maintenance nightmare.

But, if you define interfaces in the DAL, you can tell consumers of the DAL what it expects. Then you can implement those interfaces in the BL and pass instances of the interfaces instead of BL objects.

Interfaces are all about abstracting out the details of the implementation where they're not absolutely necessary.

[Edit] If you have a lot of objects that do similar things, a combination of an interface and a base class with overridable/virtual methods might be more useful than just an interface.

Wes P
+4  A: 

Interfaces are the only way to create multiple inheritance in Java.

Say you create a class Animal. And all animals, including humans extend that. And each of those animals inherits common methods like eat, breathe, etc.

But now let's say you have a MathProblem class. And you want to have certain classes that can solve that problem by passing the problem to a solve(MathProblem problem) method. And you know that a Human, but also a Computer might solve the math problem. So they both need to be able to solve that problem. You might be able to get the Computer to extend some MathSolver class that has the method, but Human already extends Animal, and can't extends anything else. So a better way is to make MathSolver an interface and have both Human, Computer, and any other classes that need to solve problems implement that.

Also note that a Human and a Computer might solve the problems in completely different ways, since their such different objects. That's what interfaces are best for. Defining certain abilities that cut across multiple inheritance hierarchies, and can have very different implementations, but can all be passed to a method that accepts any of them. Think of the Comparable interface; it's not something a certain class of objects has, all sort of things can be compared, and usually in very different ways. But you can always call sort on a List of Comparable objects since you know they have a certain order, no matter if they're Numbers, Animals, Computers or anything else (as long as they implement Comparable and define their ordering).

Andrei Fierbinteanu
+1 - I think it's important to add that there are two purposes of inheritance: (1) allow inherited-class objects to be used in place of base-class objects, and (2) allow inherited-class objects to make use of base-class behaviors. Interfaces don't do anything useful toward the second purpose, but are very helpful toward the first.
supercat
A: 

This isn't really an answer so much as an example that I find helpful when thinking about interfaces, but think about the interface Comparable<T> which requires the method

public int compareTo(T anotherObject)

The user can implement this however he or she wants. If a Person implements Comparable<Person>, for example, the comparison can be based on last name then first name, ignoring capitalization. Or it can be based on age, etc. However the user wants. Implementing this interface is very useful, in that it allows the user to use things like Collections.sort() which require that the elements to be sorted need to be comparable (how else could a comparison be made?)

A: 

Just think reverse. think about a situation where you have a few group of objects having similar clients, then you can simply extract an interface, Use the beautiful feature of OO that is Ploymorphism, and make a room for extending your implementation and having clients happy with depending upon just a contract not a concrete type. You may find most of SOLID Principles in this simple practice

Jahangir Zinedine