Visit to the bank
You walk in to the bank- to deposit cash.
You stand in the line- meet the Teller who does the transaction with you.
Do you really care whether its Joe or Mary behind the counter?
No. You do not.
Because your contract with the Bank is via the teller (:read interface) not Joe who happens to be there – that day or maybe everyday (:read implementation)
It’s all about the contract
Interface is nothing but a formal contract . All classes which implement that interface- are basically declaring that we will honor this contract and will provide you the service as said by this interface.
The beauty of this paradigm is that – this keeps your two classes blissfully unaware of each other – allowing you to change one without drastically affecting another or at least controlling the affect on another.
Java API is actually full of very good examples of this.
e.g. JDBC Driver . All JDBC applications use the Driver interface – to get a connection etc.
Because we program against this Driver- we do not care what that implementation is.
The implementation could be an Oracle Driver or a MySQL Driver.
Your application would work the same- for both the databases- as long as you have programmed to the interface- without depending upon the actual implementation.
Another example: Java Collection API List,Set,Map Interfaces.
If your classes take as input one of these interfaces- the caller may send you a different class- ArrayList or LinkedList- and you wont notice a thing. That’s why its strongly encouraged that your input parameters or return types should be an interface rather than a class.
The best thing I like about Spring is- it strongly encourages you to program to interfaces by using Config files- which bind implementing classes to each other using interfaces
You code uses only interfaces you refer to implementation only in the config file
How do I know if I did program to interfaces or not ?
Look at the input parameters and return type of your public API.
If you return a class rather than an interface- you are exposing your implementation detail.The caller is not programing to your interface -but to your classes.
If the input parameters of your public API is a class- you are dependent upon the internal implementation of the caller- and not on it’s interfaces.