How about java.lang.Runtime? java.awt.Toolkit? Although these are abstract classes and not interfaces, the same principle holds - you reference them through these abstract base classes, and don't worry about the actual implementing classes. With these two the operating system determines which implementation to use automatically.
Think about a method signature that contains "Map" vs. one that contains "HashMap" - the latter makes it impossible to ever use a different kind of Map, whereas with the former you can use any kind you want. If the method is part of a public API that many clients use, you may never be able to change it once it's released.
So, how can we say this as "Open for extension" and "closed for modification"?
I have got some idea but still not clear of the central meaning. Appreciate your help on this with some small examples...
I think one of the hardest concepts to grasp is the fact that few people ever have complete control over all the source code. You either work in teams, and team 'A' does the GUI while team 'B' does the back-end stuff, or you buy/are provided with code from a vendor.
Let's assume the latter. They tell you there is a static method called
that returns an object. this object allows you to run SQL and iterate over the rows. If you code to an interface, they can change how their widget works - they can change the actual class name, how it works...just about everything. And all you'd have to do is drop their new .jar file in over the old one.
If instead you coded to the actual object name, then you have to change the reference type...but worse, you have no promise that the method names won't change, or require different parameters, or who knows what else.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
That reminds me - JDBC also heavily depends on using interfaces. You use Connection, Statement, PreparedStatement and ResultSet - all interfaces. These are implemented by someone (like Microsoft, Oracle, IBM), but the only concrete classes you will need is java.lang.Class (for loading the driver class) and DriverManager. After loading the SQL driver class you supply a connection String, and DriverManager manages the rest. This allows you to make the entire database connection extremely pluggable. After all, you need to change only two Strings (the driver class name and the connection String) and you start using a completely different database (system). Switching from a MySQL database to an Oracle database couldn't be easier.