Tuesday, November 11, 2008

Access Protection

Access Protection:

 

In the preceding Posts, you learned about various aspects of Java's access control mechanism and its access specifiers. For example, you already know that access to a private member of a class is granted only to other members of that class. Packages add another dimension to access control. As you will see, Java provides many levels of protection to allow fine-grained control over the visibility of variables and methods within classes, subclasses, and packages.

 

Classes and packages are both means of encapsulating and containing the name space and scope of variables and methods. Packages act as containers for classes and other subordinate packages. Classes act as containers for data and code. The class is Java's smallest unit of abstraction. Because of the interplay between classes and packages, Java addresses four categories of visibility for class members:

 

Ø      Subclasses in the same package

Ø      Non-subclasses in the same package

Ø      Subclasses in different packages

Ø      Classes that are neither in the same package nor subclasses

 

The three access specifiers, private, public, and protected, provide a variety of ways to produce the many levels of access required by these categories. Table 9-1 sums up the interactions.

 

While Java's access control mechanism may seem complicated, we can simplify it as follows. Anything declared public can be accessed from anywhere. Anything declared private cannot be seen outside of its class. When a member does not have an explicit access specification, it is visible to subclasses as well as to other classes in the same package. This is the default access. If you want to allow an element to be seen outside your current package, but only to classes that subclass your class directly, then declare that element protected.

 

Table 9-1 applies only to members of classes. A class has only two possible access levels: default and public. When a class is declared as public, it is accessible by any other code. If a class has default access, then it can only be accessed by other code within its same package.

 

LANGUAGE

An Access Example

The following example shows all combinations of the access control modifiers. This example has two packages and five classes. Remember that the classes for the two different packages need to be stored in directories named after their respective

packages in this case, p1 and p2.

 

The source for the first package defines three classes: Protection, Derived, and SamePackage. The first class defines four int variables in each of the legal protection modes. The variable n is declared with the default protection, n_pri is private, n_pro is protected, and n_pub is public.

 

Each subsequent class in this example will try to access the variables in an instance of this class. The lines that will not compile due to access restrictions are commented out by use of the single-line comment //. Before each of these lines is a comment listing the places from which this level of protection would allow access.

 

The second class, Derived, is a subclass of Protection in the same package, p1. This grants Derived access to every variable in Protection except for n_pri, the private one. The third class, SamePackage, is not a subclass of Protection, but is in the same package and also has access to all but n_pri.

 

This is file Protection.java:

 

package p1;

public class Protection {

int n = 1;

private int n_pri = 2;

protected int n_pro = 3;

public int n_pub = 4;

public Protection() {

System.out.println("base constructor");

System.out.println("n = " + n);

System.out.println("n_pri = " + n_pri);

System.out.println("n_pro = " + n_pro);

System.out.println("n_pub = " + n_pub);

}

}

 

This is file Derived.java:

 

package p1;

class Derived extends Protection {

Derived() {

System.out.println("derived constructor");

System.out.println("n = " + n);

// class only

// System.out.println("n_pri = " + n_pri);

System.out.println("n_pro = " + n_pro);

System.out.println("n_pub = " + n_pub);

}

}

 

This is file SamePackage.java:

 

package p1;

class SamePackage {

SamePackage() {

Protection p = new Protection();

System.out.println("same package constructor");

System.out.println("n = " + p.n);

// class only

// System.out.println("n_pri = " + p.n_pri);

System.out.println("n_pro = " + p.n_pro);

System.out.println("n_pub = " + p.n_pub);

}

}

 

Following is the source code for the other package, p2. The two classes defined in p2 cover the other two conditions which are affected by access control. The first class, Protection2, is a subclass of p1.Protection. This grants access to all of p1.Protection's variables except for n_pri (because it is private) and n, the variable declared with the default protection. Remember, the default only allows access from within the class or the package, not extra-package subclasses. Finally, the class OtherPackage has access to only one variable, n_pub, which was declared public.

 

This is file Protection2.java:

 

package p2;

class Protection2 extends p1.Protection {

230  

Protection2() {

System.out.println("derived other package constructor");

// class or package only

// System.out.println("n = " + n);

// class only

// System.out.println("n_pri = " + n_pri);

System.out.println("n_pro = " + n_pro);

System.out.println("n_pub = " + n_pub);

}

}

 

This is file OtherPackage.java:

 

package p2;

class OtherPackage {

OtherPackage() {

p1.Protection p = new p1.Protection();

System.out.println("other package constructor");

// class or package only

// System.out.println("n = " + p.n);

// class only

// System.out.println("n_pri = " + p.n_pri);

// class, subclass or package only

// System.out.println("n_pro = " + p.n_pro);

System.out.println("n_pub = " + p.n_pub);

}

}

 

If you wish to try these two packages, here are two test files you can use. The one for package p1 is shown here:

 

// Demo package p1.

package p1;

// Instantiate the various classes in p1.

public class Demo {

public static void main(String args[]) {

Protection ob1 = new Protection();

Derived ob2 = new Derived();

SamePackage ob3 = new SamePackage();

}

}

 

The test file for p2 is shown next:

 

// Demo package p2.

package p2;

// Instantiate the various classes in p2.

public class Demo {

public static void main(String args[]) {

Protection2 ob1 = new Protection2();

OtherPackage ob2 = new OtherPackage();

}

}

No comments: