When developing software, there are basic design principles that help to cope with the complexity associated with such a complex task.
One of the main principles is the division of complex problems into smaller ones, they are easier to manage and understand.
The interface is actually a contract. It defines the services that one class should correspond to and how to use it. The interface hides the implementation details of one or more possible contract implementations.
A typical Java application will be developed with interfaces for modeling the basic contracts provided by various pieces of software. Implementation details are hidden and therefore reduce complexity.
To be more specific, let's say you are developing an accounting application. All accounts offer the same basic services: receive current balance, loan or withdraw money, request a summary of past operations. You can define an interface like this, all kinds of accounts will match:
public interface Account { double getBalance(); void credit(double amount); void withdraw(double amount); List<Operation> getOperations(Date startDate, Date endDate); }
Using this definition, it’s easy, for example, to provide a user interface that allows a user to manage their accounts. In fact, there are differences between a check, a credit card account. You will have to manage differently the account located directly in the banking database, or deleted accounts from other banks. One of them will be direct, the other is to use some kind of network protocol to perform the operation.
But from your point of view, all you need is that the contract is completed. And you can work on accounts. Information about how a particular account operation is performed is not your problem.
It is fashionable and nice, but the problem remains. How do you get your bills? The fact that this is an account from an account of another bank, of course, differs from the local account. The code is different. And a way to create it too. For a remote account, you need, for example, a network address on another bank server ... Others may require a database identifier.
Every time you need to have an account, you can explicitly recreate it or get it with all the implementation information. Getting a remote account or local account is very different.
Isolating this complexity in part of your application is good practice. It is consistent with breaking up a complex task into smaller, simpler ones.
I gave an example of an accounting application, but in fact we can be more general. Creating objects and retrieving already created objects is a very common problem in any software. Thus, we have common “good ways” to do this in a convenient and clean way.
The code that controls the complexity of creating a specific object, actually hiding how the object was created or defined, is called factory.
The combination of a factory (which hide the complexity of creating / searching for objects) and an interface (which hide the complexity of implementing each object), if the Java programmer’s tool base is used to control software complexity.