Access Control in Java

Java allows one to control access to member variables and methods. Java provides the following access levels: public, protected, package, and private. public is the most open access level: variables and methods declared public can be accessed by any class. protected is the next level of accessibility: protected variables and methods can be accessed within the same class, package, and subclass, even if the subclass is in a different package. The package, or friendly, access level is the default: this allows variables and methods to be accessed from anywhere in the same package. private is the most restrictive access level: private variables and methods can be accessed only in the current class.

In the remainder of this section, we will look at some examples of using access levels. The Private Account example shows an Account class within the bankaccount package. The class member variables all have their access level set to private. The Account constructor has no access level explicitly specified, so the package access level applies by default. We have added a method, balanceCleared, which checks that there is still money in the account. balanceCleared is invoked by the withdraw method. We make balanceCleared private because we may later decide to use a more complex formula for deciding that a balance is clear; one that may involve a different data representation. Consequently, we do not wish to expose balanceCleared to classes other than Account. Another use of private methods is to decompose a large public method into smaller private component methods that on their own make no sense outside the current class.


Private Account
package bankaccount;
class Account
{
Private int,accountNo;
Private double balance;
Private String accountName;
Account(int accountNo, String accountName, double balance)
{
this.accountNo = accountNo;
this.accountName = accountName;
this.balance = balance;
}

public double withdraw(double amount)
{
if (balanceCleared(amount))
{
balance = balance - amount;
}
else
{
System.out.println(''Insufficient Funds");
}
return balance;
}

private boolean balanceCleared(double amount)
{
if (balance - amount >= 0)
{
return true;
}
else
{
return false;
}
}
}



Consider the following statements issued from another class in the bankaccount package:

Account fredsAccount = new Account(123, "Fred", 60);
if (fredsAccount.balanceCleared(20) ) System.out.println("OK");
fredsAccount.accountName = "FRED";


The first statement is legal because the Account constructor has the package access level by default. The second statement is illegal because the balanceCleared method in the Account class has private access level. The third statement is also illegal because the accountName variable is private. A program containing the second and third statements will not compile.

A common strategy is for all instance variables in a class to be declared private; this is known as encapsulation. If there is a need for another class to access any of these variables, this can be done through methods that are declared public,protected, or package. For example, in the Account class, we could add the setAccountName method.

public void setAccountName(String newName)
{
accountName = newName;
}


The advantage of this approach is that we can add a number of data integrity checks within the setAccountName method. For example, if newName contains numeric values or its length is greater than say, 50, the assignment could fail. To use this method, we would replace the illegal statement

fredsAccount.accountName = ''FRED";

with the legal statement
fredsAccount.setAccountName("FRED");

Similarly, we can create a method, public String getAccountName(), which returns the value of accountName. getAccountName is an example of a getter, or accessor, method, and by convention, these are prefixed with get. setAccountName is an example of a setter, or mutator, method, and by convention, these are prefixed with set. These conventions are enforced by environments such as JavaBeans.

The Protected Account example illustrates the use of the protected access level. We revert to the original withdraw method, which checks the balance. Though we are prepared to allow all classes within the bankaccount package and all subclasses of Account to access variables and methods in Account, we are not prepared to expose these to all classes. So we grant all member variables, the constructor, and the withdraw method protected access level.
Note the Account class itself has public access level.

Protected Account

package bankaccount;
public class Account
{
protected int accountNo;
protected double balance;
protected string accountName;
protected Account(int accountNo, String accountName,
double balance)
{
this.accountNo = accountNo;
this.accountName = accountName;
this.balance = balance;
}

protected double withdraw(double amount)
{
if (balance - amount < 0)
{
System.out.println("Insufficient Funds");
}
Else
{

balance = balance - amount;
}
return balance;
}
}


The SubAccount class is a subclass of Account that belongs to the salesaccount package. This subclass does not do very much; it just consists of a constructor that invokes the parent, Account, class constructor using the super keyword.


SubAccount
package salesaccount;

import bankaccount.*;

class SubAccount extends Account
{
double minBalance;

SubAccount(int no, String name, double balance)
{
super(no, name, balance);
}
}




Note that line 5 is legal since the Account class in the Protected Account example was declared public. By default, a class has package access level, which means a subclass can only be created in the same package. Line 9 is also legal since this statement invokes the protected Account constructor in the Account class.

The following statements issued by a program that is within the salesaccount package, but is not a subclass of Account, are all illegal:

Account shamsasAccount = new Account(456, ''Shamsa", 70);
balance=shamsasAccount.withdraw(10); shamsasAccount.accountName = "SHAMSA";


The first statement is illegal because the Account constructor in the Protected Account example is protected, so it can only be accessed outside the bankaccount package from a subclass of Account. The second statement is illegal because the withdraw method is protected. The third statement is illegal because the accountName variable is protected. Note that the preceding three statements would all be legal if they were placed in the bankaccount package.

Java access levels.

The Above shown figure is an java access levels. A vertical line represents a subclass relationship,so class B is a subclass of class A. Assume the protection levels are set in class A. Then the following classes can access methods and variables in class A:


public classes A, B, C, D, and E

protected classes A, B, C, and D

package, or classes A, B, and D
friendly

private class A

No comments:

Post a Comment