Inner Classes

Non-static nested classes are called inner classes. Non-static class members are associated with instances of a classnon-static fields are instance variables and non-static methods operate on an instance. Similarly, an inner class is also (usually) associated with an instance of a class, or more specifically an instance of an inner class is associated with an instance of its enclosing classthe enclosing instance or enclosing object.

You often need to closely tie a nested class object to a particular object of the enclosing class. Consider, for example, a method for the BankAccount class that lets you see the last action performed on the account, such as a deposit or withdrawal:

public class BankAccount
{
private long number; // account number
private long balance; // current balance (in cents)
private Action lastAct; // last action performed

public class Action
{
private String act;
private long amount;
Action(String act, long amount)
{
this.act = act;
this.amount = amount;
}
public String toString()
{
// identify our enclosing account
return number + ": " + act + " " + amount;
}
}

public void deposit(long amount)
{
balance += amount;
lastAct = new Action("deposit", amount);
}

public void withdraw(long amount)
{
balance -= amount;
lastAct = new Action("withdraw", amount);
}
// ...
}



The class Action records a single action on the account. It is not declared static, and that means its objects exist relative to an object of the enclosing class.

The relationship between an Action object and its BankAccount object is established when the Action object is created, as shown in the deposit and withdraw methods. When an inner class object is created, it must be associated with an object of its enclosing class. Usually, inner class objects are created inside instance methods of the enclosing class, as in deposit and withdraw. When that occurs the current object this is associated with the inner object by default. The creation code in deposit is the same as the more explicit

lastAct = this.new Action("deposit", amount);



Any BankAccount object could be substituted for this. For example, suppose we add a transfer operation that takes a specified amount from one account and places it in the current accountsuch an action needs to update the lastAct field of both account objects:

public void transfer(BankAccount other, long amount)
{

other.withdraw(amount);
deposit(amount);
lastAct = this.new Action("transfer", amount);
other.lastAct = other.new Action("transfer", amount);
}



In this case we bind the second Action object to the otherBankAccount object and store it as the last action of the other account. Each BankAccount object should only refer to Action objects for which that BankAccount object is the enclosing instance. It would make no sense above, for example, to store the same Action object in both the current lastAct field and other.lastAct.

An inner class declaration is just like a top-level class declaration except for one restrictioninner classes cannot have static members (including static nested types), except for final static fields that are initialized to constants or expressions built up from constants. The rationale for allowing constants to be declared in an inner class is the same as that for allowing them in interfacesit can be convenient to define constants within the type that uses them.


We Are Founder..