WebReference.com - Part 5 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (3/6) | WebReference

WebReference.com - Part 5 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (3/6)

To page 1To page 2current pageTo page 4To page 5To page 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().


To page 1To page 2current pageTo page 4To page 5To page 6
[previous] [next]

Created: August 5, 2002
Revised: August 5, 2002

URL: https://webreference.com/programming/java/beginning/chap5/5/3.html