Here is the definition for "encapsulation" in the book The Java Tutorial 2nd ed -"Hiding information within an object's nucleus and then providing a public interface for interacting with it is called encapsulation". The definition in Marcus Green's Tutorial is the same. However, what specifically does this mean? Which of the following would be true statements to describe the concept of encapsulation? Variables must be private? Variables must be public? Methods must be private? Methods must be public? Classes must be private? Classes must be public? Constructors must be private? Constructors must be public? Something else - like maybe - objects can only be modified via instanciating a method? Or objects can only be modified via instanciating a class? Thanks!
Don't get hung up on details. Encapsulation is a nicely vague concept, which could include most of what you've listed. Probably the most popular way of using encapsulation is make all member variables private and provide access methods to set and/or get them. This may sound a bit pointless at first - why provide extra code when just using the variable would be much simpler? The payoff comes when setting the value might be dangerous or accessing the value needs to perform some sort of side effect. Here's a little example. The class without encapsulation:
In the above, independently accessing either of the member variables is dangerous. The two variables must be kept in step, but any other code could assign to either of them and completely break the operation of Example. Using encapsulation makes the code a little larger, but much safer and easier to extend or maintain:
Just making the member variables private has already gained us the benefits of safety, but we have lost the useful ability to see how many values are currently stored. In the original version, that was available in "count". So if client software needs to know this, we can add a "getter".
This is still safe, but provides the facility we needed. Now imagine someone reminds us that there is a useful system class (Vector) which does this sort of thing, and is generally better and more flexible. Converting the original to use a Vector would be almost impossible. We would have to separately maintain the public "count" variable, just in case any client software wanted to read it. Yuck. In the new encapsulated version, changing the internals of the class to use a Vector, has no effect on the public interface at all, so other classes don't even need to be recompiled!
This was obviously a bit of a simplistic example, but I hope it helped to explain the essence of encapsulation, and the reasons behind it. As a rule of thumb, make everything private unless you really have to make it part of the public interface of the class and are willing for it to be "set in stone".
For me, the thing I like most about encapsulation is that you can improve how the object stores its stuff and works while the interface stays the same. Suppose you have a MyDate class that stores a date as three integers (year, month, day). You provide all the getters and setters and all is well. Later, you decide that you need to save memory and you do a lot of date math, so you change the innards to be one int that represents the number of days since Jan 1 , 1900. Now all of your getters and setters for year, month and day have to do some computation, but everything still works the way you would expect.
Which neatly leads onto a book recommendation: "Refactoring: Improving the design of existing code" by Martin Fowler (http://www.amazon.com/exec/obidos/ASIN/0201485672) is a must-read for Java developers. It's the best programming book I've read in a long time, and the examples are all in Java. This book can really help anyone to get a good understanding of the practical application of not just encapsulation, but lots of other popular but confuding O-O practices. I know I'm enthusing, but I got this book a few months ago, and I tink it's great. Check out the reviews on Amazon.