By specifying member accessibility modifiers, a class can control what information is accessible to clients (i.e., other classes). These modifiers help a class to define a contract so that clients know exactly what services are offered by the class.
Accessibility of members can be one of the following:
public
protected
default (also called package accessibility)
private
A member has package or default accessibility when no accessibility modifier is specified.
In the following discussion on accessibility modifiers for members of a class, keep in mind that the member accessibility modifier only has meaning if the class (or one of its subclasses) is accessible to the client. Also, note that only one accessibility modifier can be specified for a member. The discussion in this section applies to both instance and static members of top-level classes. Discussion of member accessibility for nested classes is deferred to Chapter 7.
In UML notation the prefixes + , #, and -, when applied to a member name, indicate public, protected, and private member accessibility, respectively. No prefix indicates default or package accessibility.
Public accessibility is the least restrictive of all the accessibility modifiers. A public member is accessible from anywhere, both in the package containing its class and in other packages where this class is visible. This is true for both instance and static members.
Example 4.9 contains two source files, shown at (1) and (6). The package hierarchy defined by the source files is depicted in Figure 4.4, showing the two packages packageA and packageB containing their respective classes. Classes in package packageB use classes from package packageA. SuperclassA in packageA has two subclasses: SubclassA in packageA and SubclassB in packageB.
// Filename: SuperclassA.java (1) package packageA; public class SuperclassA { public int superclassVarA; // (2) public void superclassMethodA() {/*...*/} // (3) } class SubclassA extends SuperclassA { void subclassMethodA() { superclassVarA = 10; } // (4) OK. } class AnyClassA { SuperclassA obj = new SuperclassA(); void anyClassMethodA() { obj.superclassMethodA(); // (5) OK. } } _________________________________________________________________________________ // Filename: SubclassB.java (6) package packageB; import packageA.*; public class SubclassB extends SuperclassA { void subclassMethodB() { superclassMethodA(); } // (7) OK. } class AnyClassB { SuperclassA obj = new SuperclassA(); void anyClassMethodB() { obj.superclassVarA = 20; // (8) OK. } }
Accessibility is illustrated in Example 4.9 by the accessibility modifiers for the field superclassVarA and the method superclassMethodA at (2) and (3), respectively, defined in class SuperclassA. These members are accessed from four different clients in Example 4.9.
Client 1: From a subclass in the same package, which accesses an inherited field. SubclassA at (4) is such a client.
Client 2: From a non-subclass in the same package, which invokes a method on an instance of the class. AnyClassA at (5) is such a client.
Client 3: From a subclass in another package, which invokes an inherited method. SubclassB at (7) is such a client.
Client 4: From a non-subclass in another package, which accesses a field in an instance of the class. AnyClassB at (8) is such a client.
In Example 4.9, the field superclassVarA and the method superclass MethodA have public accessibility, and are accessible by all the four clients listed above. Subclasses can access their inherited public members by their simple name, and all clients can access public members through an instance of the class. Public accessibility is depicted in Figure 4.4.
A protected member is accessible in all classes in the package containing its class, and by all subclasses of its class in any package where this class is visible. In other words, non-subclasses in other packages cannot access protected members from other packages. It is less restrictive than the default accessibility.
In Example 4.9, if the field superclassVarA and the method superclass MethodA have protected accessibility, then they are accessible within package packageA, and only accessible by subclasses in any other packages.
public class SuperclassA { protected int superclassVarA; // (2) protected void superclassMethodA() {/*...*/} // (3) }
Client 4 in package packageB cannot access these members, as shown in Figure 4.5.
A subclass in another package can only access protected members in the superclass via references of its own type or its subtypes. The following new definition of SubclassB in packageB from Example 4.9 illustrates the point:
// Filename: SubclassB.java package packageB; import packageA.*; public class SubclassB extends SuperclassA { // In packageB. SubclassB objRefB = new SubclassB(); // (1) void subclassMethodB(SuperclassA objRefA) { objRefB.superclassMethodA(); // (2) OK. objRefB.superclassVarA = 5; // (3) OK. objRefA.superclassMethodA(); // (4) Not OK. objRefA.superclassVarA = 10; // (5) Not OK. } }
The class SubclassB defines a field of type SubclassB (objRefB). The method subclassMethodB() has a formal parameter objRefA of type SuperclassA. Access is permitted to a protected member of the SuperclassA in packageA by a reference of the subclass, as shown at (2) and (3), but not by a reference of its superclass, as shown at (4) and (5). References to the field superclassVarA and the call to superclassMethodA() occur in SubclassB. These members are declared in SuperclassA. SubclassB is not involved in the implementation of a SuperclassA, which is the type of objRefA. Hence access to protected members at lines (4) and (5) is not permitted as these are not members of an object that can be guaranteed to be implemented by the code accessing them.
Accessibility to protected members of the superclass would be permitted via any references of subclasses of SubclassB. The above restriction helps to ensure that subclasses in packages different from their superclass can only access protected members of the superclass in their part of the implementation inheritance hierarchy.
When no member accessibility modifier is specified, the member is only accessible by other classes in its class's package. Even if its class is visible in another (possibly nested) package, the member is not accessible there. Default member accessibility is more restrictive than protected member accessibility.
In Example 4.9, if the field superclassVarA and the method superclass MethodA are defined with no accessibility modifier, then they are only accessible within package packageA, but not in any other (possibly nested) packages.
public class SuperclassA { int superclassVarA; // (2) void superclassMethodA() {/*...*/} // (3) }
The clients in package packageB (i.e. Clients 3 and 4) cannot access these members. This situation is depicted in Figure 4.6.
This is the most restrictive of all the accessibility modifiers. Private members are not accessible from any other class. This also applies to subclasses, whether they are in the same package or not. Since they are not accessible by simple name in a subclass, they are also not inherited by the subclass. This is not to be confused with the existence of such a member in the state of an object of the subclass (see Section 8.2, p. 342). A standard design strategy is to make all fields private, and provide public accessor methods for them. Auxiliary methods are often declared private, as they do not concern any client.
In Example 4.9, if the field superclassVarA and the method superclass MethodA have private accessibility, then they are not accessible by any other clients.
public class SuperclassA { private int superclassVarA; // (2) private void superclassMethodA() {/*...*/} // (3) }
None of the clients in Figure 4.7 can access these members.
Modifiers | Members |
---|---|
public | Accessible everywhere. |
protected | Accessible by any class in the same package as its class, and accessible only by subclasses of its class in other packages. |
default (no modifier) | Only accessible by classes, including subclasses, in the same package as its class (package accessibility). |
private | Only accessible in its own class and not anywhere else. |