WebReference.com - Part 5 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (3/6)
[previous] [next] |
Beginning Java 2 SDK 1.4 Edition
Using a Non-Static Nested Class
In our previous example, we could define the Rabbit class as non-static by deleting
the keyword static. However, if you try that, the program will no longer compile and
run. The problem is the static data members' rabbitNames and rabbitNamesCount
in the Rabbit class. We saw earlier that a non-static nested class cannot have static
members, so we must seek an alternative way of dealing with names.
We could consider making these arrays non-static. This has several disadvantages. First, each
Rabbit object would have its own copy of these arrays--an unnecessary duplication of
data. A more serious problem is that our naming process would not work. Because each object has its
own copy of the rabbitNamesCount array, the names generated are not going to be unique.
The answer is to keep rabbitNames and rabbitNamesCount as static, but put
them in the MagicHat class instead. Let's see that working.
Try It Out--Accessing the Top Level Class Members
We need to modify the class definition to:
public class MagicHat {
static int maxRabbits = 5; // Maximuum rabbits in a hat
static Random select = new Random(); // Random number generator
static private String[] rabbitNames = {"Floppsy", "Moppsy",
"Gnasher", "Thumper"};
static private int[] rabbitNamesCount = new int[rabbitNames.length];
// Constructor for a hat
public MagicHat(final String hatName) {
this.hatName = hatName; // Store the hat name
rabbits = new Rabbit[1+select.nextInt(maxRabbits)]; // Random rabbits
for(int i = 0; i < rabbits.length; i++)
rabbits[i] = new Rabbit(); // Create the rabbits
}
// String representation of a hat
public String toString() {
// Hat name first...
String hatString = "\n" + hatName + " contains:\n";
for(int i = 0; i < rabbits.length; i++)
hatString += "\t" + rabbits[i] + " "; // Add the rabbits strings
return hatString;
}
private String hatName; // Name of the hat
private Rabbit rabbits[]; // Rabbits in the hat
// Nested class to define a rabbit
class Rabbit {
private String name; // Name of the rabbit
// Constructor for a rabbit
public Rabbit() {
int index = select.nextInt(rabbitNames.length); // Get random name index
name = rabbitNames[index] + (++rabbitNamesCount[index]);
}
// String representation of a rabbit
public String toString() {
return name;
}
}
}
The only changes are the deletion of the static keyword in the definition of the
Rabbit class--the data members relating to rabbit names have been moved to the
MagicHat class. You can run this with the same version of TryNestedClass and
it should produce output much the same as before.
How it Works
Although the output is much the same, what is happening is distinctly different. The Rabbit
objects that are created in the MagicHat constructor are now associated with the current
MagicHat object that is being constructed. The Rabbit() constructor call is
actually this.Rabbit().
[previous] [next] |
Created: August 5, 2002
Revised: August 5, 2002
URL: http://webreference.com/programming/java/beginning/chap5/5/3.html

Find a programming school near you