As you have said, interfaces are used to specify contracts which classes that implement them must follow. The scenarios in which they are used is usually a scenario where you call a class which implements a particular interface. The fact that the implements a particular interface provides you with the knowledge that that given class, does indeed implement a given set of methods. Usually you do not care what happens in these methods, what matters to you is that the class has these methods.
As an example, you might want to consider the Observer Design Pattern. Basically, you have one object that has a state which it shares with other objects and passes to them notifications when some of its data changes.
So, if for instance all the observers implement the following interface:
public interface Observer
{
notify();
}
The Subject can, without any knowledge what so ever about it's observers, do something like this:
public class MySubject...
{
List<Observer> observers;
.....
public void notifyAll()
{
for (Observer observer : observers)
{
observer.notify();
}
}
}
As you can see, the MySubject
class does not have any knowledge of how the Observer implements the notify
method, what it really cares about is that it implements it. This allows you to create different observers which have different ways of implementing their own notify
class without requiring any changes in the MySubject
class.
Interfaces also allow for certain type safety. Interfaces are usually also handy when you have a series of classes implementing a series of similar behaviours which you usually want to store into some type-safe data structure. This is usually a good work around the fact that Java does not allow multiple inheritance. So, in the example provided above, I can have an indefinite amount of different classes. But as long as they all implement the Observer
interface, they can all be added to the same list.
In the notifyAll
methods, then I can just iterate of the elements of the list instead of checking if the element is of a certain type and then casting it, which can introduce some extra overhead in the program's execution.