After a decade+ using Java, I find myself questioning the big 3 OO principles (the most over-used interview question ever): inheritance, encapsulation, and polymorphism. Or maybe more precisely I question the typical Java expression of these principles.
Encapsulation sounds great and all but in Java as typically practiced it’s mostly a joke. We create our objects with private (mutable!) data but expose most of it through public getters and setters. We then struggle to properly manage that mutable state in the face of concurrency problems.
Inheritance sounds great but in a single-inheritance language is a very strong coupling. Inheritance creates issues in equality, in patterns like the template method, in just simply modeling many common domains.
Polymorphism sounds great and it actually is pretty great. :) Any Java developer worth his bytecode knows how important the use of interfaces is in writing modular, maintainable code. Interface-oriented programming is the cornerstone of dependency injection and the key to most of the design patterns we use every day. My only complaint about interface-oriented Java is that it typically results in large number of classes and interfaces, thus increasing the surface area of your code base.
As I dig into Clojure more and more I see that it fares pretty well in providing the best of Java OO (polymorphism via multimethods and in the future protocols) without the downsides of encapsulation and inheritance. I wish I knew Smalltalk so I could defend OO better as I suspect the issues above are more due to OO in Java than OO as concept.
Must go find my flame-resistant suit now…. :)