Saturday, 12 December 2009

Access modifiers in Java

Access modifiers specifies who can access them. There are four access modifiers used in java. They are :
  • public
  • private
  • protected
  • no modifer (declaring without an access modifer). Using ‘no modifier’ is also sometimes referred as ‘package-private’ or ‘default’ or ‘friendly’ access.
Usage of these access modifiers is restricted to two levels. The two levels are class level access modifiers and member level access modifiers.

I) Class level access modifiers (java classes only)

Only two access modifiers is allowed, public and no modifier
  • If a class is ‘public’, then it CAN be accessed from ANYWHERE.
  • If a class has ‘no modifer’, then it CAN ONLY be accessed from ‘same package’.

II) Member level access modifiers (java variables and java methods)

All the four public, private, protected and no modifer is allowed.
  • public and no modifier – the same way as used in class level.
  • private – members CAN ONLY access.
  • protected – CAN be accessed from ‘same package’ and a subclass existing in any package can access.
Understanding by the table below

For better understanding, member level access is formulated as a table:

Access Modifiers

Same Class Same Package Subclass Other packages
public Y Y Y Y
protected Y Y Y N
no access modifier Y Y N N
private Y N N N

First row {public Y Y Y Y} should be interpreted as:

  • Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘same class’.
  • Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘same package’.
  • Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘subclass’.
  • Y – A member declared as ‘public’ CAN be accessed from ‘Other packages’.

Second row {protected Y Y Y N} should be interpreted as:

  • Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘same class’.
  • Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘same package’.
  • Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘subclass’.
  • N – A member declared with ‘protected’ access modifier CANNOT be accessed by the members of the ‘Other package’.

similarly interpret the access modifiers table for the third (no access modifier) and fourth (private access modifier) records.

Examples
Public Members:
For a subclass, if a member of its superclass is declared public, the subclass inherits that member regardless of whether both classes are in the same package.

package pack1;
public class Parent {
public String getName() {
return “Parent”;
}
}

package pack2;
Import pack1.Parent;
Public class Child extends Parent{
Public String getParentsName() {
return getName();
}
}

If you see the example above, the child class is able to access the parent class’s method getName() even without instantiating an object of the parent because it inherits the Parent class and all its method as part of the inheritance (extends) feature.

Private Members:
Members marked private can’t be accessed by code in any class other than the class in which the private member was declared. Let’s make a small change to the Parent class from an earlier example.

package pack1;
public class Parent {
private String getName() {
return “Parent”;
}
}

Now the getName() method is private and is not visible from within the Child class and the same piece of code would throw up the below compilation error when you try to compile the class.

cannot find symbol
symbol : method getName()
This error method looks as if the method getName() does not exist at all. Of course the method exists but unfortunately it is declared private and hence no class (except the class that has the exact code written into it) can access it. This includes a child class that extends the parent class that has the method.
Note: You can write a method inside the child class that has the same name as the private method in the parent. This does not account as Overriding because the parent class method is not even visible and hence it is just another method and is not considered overriding.

Tip: Though you may feel that public is better because all other classes can access your methods, that is seldom the case because a code that is visible to all other classes is not secure and that is not the best way to write your code. It is always best to provide just the appropriate level of access to methods and variables instead of having all of them public.

Protected and Default Members:
The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
Take a look at the following two classes:

package certification;
public class ClassOne {
void testIt() { // No modifier means method has default access
System.out.println("ClassOne");
}
}

In another source code file you have the following:

package otherCertification;
import certification.ClassOne;
class ClassTwo {
static public void main(String[] args) {
ClassOne o = new ClassOne();
o.testIt();
}
}

As you can see, the testIt() method in the first file has default (think: package-level) access. Notice also that class OtherClass is in a different package from the AccessClass. When you compile the ClassTwo.java file you will get an error like below:
No method matching testIt() found in class
certification.ClassOne.o.testIt();
From the preceding results, you can see that AccessClass can’t use the OtherClass method testIt() because testIt() has default access, and AccessClass is not in the same package as OtherClass. So AccessClass can’t see it, the compiler complains.
Default and protected behavior differs only when we talk about subclasses. If the protected keyword is used to define a member, any subclass of the class declaring the member can access it through inheritance. It doesn’t matter if the superclass and subclass are in different packages, the protected superclass member is still visible to the subclass. This is in contrast to the default behavior, which doesn’t allow a subclass to access a superclass member unless the subclass is in the same package as the superclass. (See the example above)
Whereas default access doesn’t extend any special consideration to subclasses, the protected modifier respects the parent-child relationship, even when the child class moves away (and joins a new package). So, when you think of default access, think of package restrictions. No exceptions at all. But when you think protected, think package + kids. A class with a protected member is marking that member as having package-level access for all classes, but with a special exception for subclasses outside the package.


Tip: Remember that Default and Protected access is the same as long as inheritance is not involved.


Local Variables and Access Modifiers

Can access modifiers be applied to local variables? A BIG NO!
There is never a case where an access modifier can be applied to a local variable, so watch out for code like the following:


class Test {
void doTest() {
private int x = 7; //Not Possible
this.doSomethingElse(x);
}
}

The above code will not compile or run. Dont think that the private keyword is legal inside the method doTest().
You can be certain that any local variable declared with an access modifier will not compile. In fact, there is only one modifier that can ever be applied to local variables—final.


 


 

No comments:

Post a Comment