is a fundamental principle in Object Oriented Programming to build Software Applications that can change more easily and quickly. A lot of other principles and Design Patterns are based on the principle. Interface is mostly viewed as a useful feature for writing more maintainable code. Program to Interface Program to Interface However, the concept of Interface came around to solve a different problem. Author has explained this in his book in great detail. We will try to understand the gist of it in this post. Don Box Essential COM The explanation is in the context of C++. I am not a C++ programmer. I have covered high level explanation of the concepts here. If you are interested in details, I would recommend to refer to the first chapter of the book Essential COM What lead to Interface Before we go further, it is better to quickly refresh the role of a Compiler and a Linker in C++ as shown in Figure 1. Compiler converts C++ source code to assembly code, and the Linker then combines all assembly code and external libraries in to one executable or library file output. It is common to abstract out common logic or functionality into libraries. This makes the system modular and allows easy reuse. Let's say there is a library named implementing functions of a Calculator. Following is a subset of the functions: calclib // calc.h ///////////////////////////// class Calculator { float pi; public: Calculator(); ~Calculator(void); float add(float a, float b); //add two numbers } ; This library is then used in application by including the file in source code of and providing to the Linker which will generate executable containing the as shown in Figure 2. CalcApp calc.h CalcApp calclib CalcApp calclib This is called . If there is any update to , the application has to be re-compiled and distributed again. Any change requires lot of effort and time. This can be a problem for libraries that are used in many applications. Static Linking calclib CalcApp This problem was solved with . Such libraries are loaded at run time and the actual wiring of method calls (at binary level) happens when the Application is run. While building the application, the Linker would insert stubs in the application executable to make this possible. DLL makes it possible to just distribute new version of the library and the application will start working with updated version. Dynamic Link Library (DLL) Let's say adds new feature of keeping last result in memory and allowing to retrieve it. calclib 2.0 // calc.h ///////////////////////////// class Calculator { float pi; float lastResult; //added in v2.0 public: Calculator(); ~Calculator(void); float add(float a, float b); //add two numbers float getLastResult(); //added in v2.0 } ; method saves the result in add lastResult public float add(float a, float b) { lastResult = a + b; return lastResult; } There three changes to Calculator class in v2.0: A new private member variable lastResult A new public method getLastResult Minor change to method implementation. Change does not alter the expected behavior for the client. add In theory, this should just work because none of these changes break anything for the client. But it doesn't! Here is why it doesn't work: When an object of class is created, memory is allocated based on its private members as shown in Figure 4. Calculator When was compiled with , the Compiler would have generated code to when compiling following code: CalcApp calclib 1.0 allocate 4 bytes for one private member Calculator *c = new Calculator(); Now when runs with , the Calculator object would have been allocated 4 bytes for one private member according to implementation. But . So that causes an error. CalcApp calclib 2.0 calclib 1.0 the add method in v2.0 tries to access lastResult for which no memory is allocated . This is contrary to the principle of in Object Oriented Programming. That means making changes to a Class implementation that are private and have no impact on the publicly exposed functionality can also break the System Encapsulation Don Box writes C++ supports syntactic encapsulation but . has no notion of binary encapsulation Root cause of the problem is that . the memory allocation for an Object is determined by the Compiler at the time of compilation, and it is hard-wired in the binary output based on size of object at compile time, but with DLL the size of object can change resulting in errors when application is run with different version than it was compiled with The solution: . Let client refer only the interface as shown in Figure 5. separate the interface from the implementation and delegate responsibility of creating objects to the implementation How Interface solves the problem? Interface has only public method declaration. No private members or method implementation. Factory is used to create an instance of the implementation so the implementation can change without breaking its clients e.g., adding a new private member variable in will not break clients compiled with earlier version because Factory in v2.0 will allocate appropriate memory. calclib 2.0 This allows both the client and the library to change independently. Change in public method signature will break the clients. That's why an Interface is not modified once in use, but it is versioned to keep backward compatibility. Interface in C++ Newer programming languages like Java, C#, etc. have explicit support for Interface. C++ has no built-in support for Interface, so Abstract class with only pure virtual functions are used to define an Interface. Java (JVM languages) and C# Dynamic loading of libraries is common in all newer programming languages like Java, C#, etc. But they do not face the problem we just discussed. Why? Two reasons: All these languages are compiled to an intermediate code (Bytecode, IL Code) and this intermediate code is converted to machine code by the Runtime (JVM, CLR) when the application is run - Just-in-time compilation (JIT). Therefore, practically the linking process (or equivalent to that) happens on every execution. Any changes to a library will be picked up by the Runtime during execution. The memory management is handled by the Runtime (JVM, CLR). The runtime can allocate appropriate memory depending on the latest implementation. Hope you found this interesting. Please share your feedback in the comments.