Encapsulation: Private, Public, Friendly, and Protected
It is often desirable to hide certain aspects of a class from public view: one may not want to bother a user with unnecessary details, or one would like to prevent unauthorized access to data. To prevent this from happening, a process called data encapsulation is used:
Encapsulation using Private, Public, Friendly, or Protected
public: a field, method, or class that is accessible to every class | |
protected: a field, method, or class that is accessible to the class itself, subclasses, and all classes in the same package or directory. | |
friendly: a field, method, or class that is accessible to the class itself and to all classes in the same package or directory. Note that friendly is not a separate keyword. A field or method is declared friendly by virtue of the absence of any other access modifiers. | |
private: a field or method that is accessible only to the class in which it is defined. Note that a class can not be declared private as a whole. |
We will usually deal with small to medium sized projects where all classes reside in the same directory. Hence, for those classes there is little difference between friendly and protected; the modifiers public and private will be the more useful ones for us.
Example:
We need to write two classes: one class with various fields, and a second class to attempt to access these fields. Here is an example:
When trying to compile the class Tester, Java will print the following error message:
That is because the class Tester can not access the private field in the AccessTest class. If the offending line is removed from the Tester class, everything will compile fine, and the output would be the numbers 3 and 4.
The above definition of private leads to an interesting question: if a class declares a field to be private, and two objects of the same class exist, can they access each others private fields? That situation rarely happens, and will be skipped. Refer to a book on Java for details. Similarly, one could construct another technical examples to highlight the differences between protected and friendly. However, in most of our projects we will be content with using private and public access, and therefore we will focus on those modifiers.
To help with deciding when to use which access modifier, here is a rule of thumb.
Constructors and destructors should never be declared private by virtue of what they try to accomplish. Private and public are the most common access modifiers used, while friendly access (i.e. no modifier keyword) is frequently used to allow for inheritance of fields without allowing global access.
Example:
We do not need to change the implementation of our methods. We simply change the field declarations and method headers as follows, according to our rule of thumb:
Note that the private fields width and height can not be accessed directly any more,
but the public method setDimensions, in turn, can access those fields. That method can act
as a kind of filter, if necessary, preventing a user from destroying the integrity of the
class. In fact, such methods happen frequently.
Frequently, classes may also have private methods in addition to private fields. Those would be only of use for the internal workings of the class, and should not be made public either to shield the user from any unnecessary complexities, or to maintain, as before, the integrity of the class. Such private methods are frequently called utility methods.
We will later see many examples of set and get methods, as well as plenty of utility
methods.