O'Reilly logo

Essential ActionScript 3.0 by Colin Moock

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 4. Static Variables and Static Methods

In Chapter 1, we learned how to define the characteristics and behavior of an object using instance variables and instance methods. In this chapter, we'll learn how to manage information and create functionality that pertains to a class, itself, rather than its instances.

Static Variables

Over the past several chapters, we've had a fair bit of practice working with instance variables, which are variables associated with a particular instance of a class. Static variables, by contrast, are variables associated with a class itself, rather than a particular instance of that class. Static variables are used to keep track of information that relates logically to an entire class, as opposed to information that varies from instance to instance. For example, a class representing a dialog box might use a static variable to specify the default size for new dialog box instances, or a class representing a car in a racing game might use a static variable to specify the maximum speed of all car instances.

Like instance variables, static variables are created using variable definitions within class definitions, but static variable definitions must also include the static attribute, as shown in the following generalized code:

class SomeClass {
  static var identifier = value;
}

As with instance variables, access-control modifiers can be used to control the accessibility of static variables in a program. The access-control modifiers available for static-variable definitions are identical to those available for instance-variable definitions—public, internal, protected, and private. When no modifier is specified, internal (package-wide access) is used. When a modifier is specified, it is typically placed before the static attribute, as shown in the following code:

class SomeClass {
  private static var identifier = value;
}

To access a static variable, we provide the name of the class that defines the variable, followed by a dot (.), followed by the name of the variable, as shown in the following generalized code:

SomeClass.identifier = value;

Within the class that defines the variable, identifier can also be used on its own (without the leading class name and dot). For example, in a class, A, that defines a static variable v, the expression A.v is identical to the expression v. Nevertheless, to distinguish static variables from instance variables, many developers (and this book) include the leading class name even when it is not strictly required.

Static variables and instance variables of the same name can coexist within a class. If a class, A, defines an instance variable named v, and a static variable, also named v, then the identifier v on its own refers to the instance variable, not the static variable. The static variable can be accessed only by including the leading class name, as in A.v. The instance variable is, therefore, said to shadow the static variable.

Now let's add some static variables to our VirtualPet class. As we just learned, static variables are used to keep track of information that relates logically to an entire class and does not vary from instance to instance. There are already two such pieces of information in our VirtualPet class: the maximum length of a pet's name and the maximum number of calories a pet can consume. To track that information, we'll add two new static variables: maxNameLength and maxCalories. Our variables are not required outside the VirtualPet class, so we'll define them as private. The following code shows the maxNameLength and maxCalories definitions, with the rest of the VirtualPet class code omitted in the interest of brevity:

package zoo {
  internal class VirtualPet {
    private static var maxNameLength = 20;
    private static var maxCalories = 2000;

    // Remainder of class not shown...
  }
}

With our maxNameLength and maxCalories variables in place, we can now update the getHunger( ), eat( ), and setName( ) methods to use those variables. Example 4-1 shows the latest version of the VirtualPet class, complete with static variables. Changes since the previous version are shown in bold. Notice that, by convention, the class's static variables are listed before the class's instance variables.

Example 4-1. The VirtualPet class

package zoo {
  internal class VirtualPet {
    private static var maxNameLength = 20;
    private static var maxCalories = 2000;

    private var petName;
    // Give each pet 50% of the maximum possible calories to start with.
    private var currentCalories = VirtualPet.maxCalories/2;

    public function VirtualPet (name) {
      setName(name);
    }

    public function eat (numberOfCalories) {
      var newCurrentCalories = currentCalories + numberOfCalories;
      if (newCurrentCalories > VirtualPet.maxCalories) {
        currentCalories = VirtualPet.maxCalories;
      } else {
        currentCalories = newCurrentCalories;
      }
    }

    public function getHunger () {
      return currentCalories / VirtualPet.maxCalories;
    }

    public function setName (newName) {
      // If the proposed new name has more than maxNameLength characters...
      if (newName.length > VirtualPet.maxNameLength) {
        // ...truncate it
        newName = newName.substr(0, VirtualPet.maxNameLength);
      } else if (newName == "") {
        // ...otherwise, if the proposed new name is an empty string,
        // then terminate this method without changing petName
        return;
      }

      // Assign the new, validated name to petName
      petName = newName;
    }

    public function getName () {
      return petName;
    }
  }
}

In Example 4-1, notice that the maxNameLength and maxCalories variables help centralize our code. For example, previously, to update the maximum allowed number of characters in a name, we would have had to change the number 20 in two places within the setName method—a process that is both time-consuming and prone to error. Now, to update the maximum allowed number of characters, we simply change the value of maxNameLength, and the entire class updates automatically.

Tip

Unexplained literal values such as the number 20 in the previous version of setName( ) are known as "magic values" because they do something important, but their purpose is not self-evident. Avoid using magic values in your code. In many cases, static variables can be used to keep track of values that would otherwise be "magic."

Static variables are often used to maintain settings whose values should not change once a program has started. To prevent a variable's value from changing, we define that variable as a constant, as discussed in the next section.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required