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

Static Methods

In the preceding section we learned that static variables are used to track information that relates to an entire class. Similarly static methods define functionality that relate to an entire class, not just an instance of that class. For example, the Flash runtime API includes a class named Point that represents a Cartesian point with an x-coordinate and a y-coordinate. The Point class defines a static method, polar( ), which generates a Point object based on a given polar point (i.e., a distance and an angle). Conceptually, converting a polar point to a Cartesian point is a general service that relates to Cartesian points in general, not to a specific Point object. Therefore, it is defined as a static method.

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

class SomeClass {
  static function methodName (identifier1 = value1,
                              identifier2 = value2,
                              ...
                              identifiern = valuen) {
  }
}

As with instance methods, access-control modifiers can control the accessibility of static methods in a program. The access-control modifiers available for static-methods definitions are identical to those available for instance-method definitions—namely: 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 {
  public static function methodName (identifier1 = value1,
                                     identifier2 = value2,
                                     ...
                                     identifiern = valuen) {
  }
}

To invoke a static method, we use the following general code:

SomeClass.methodName(value1, value2,...valuen)

In the preceding code, SomeClass is the class within which the static method is defined, methodName is the name of the method, and value1, value2,...valuen is a list of zero or more method arguments. Within the class that defines the method, methodName can be used on its own (without the leading class name and dot). For example, in a class, A, that defines a static method m, the expression A.m( ) is identical to the expression m( ). Nevertheless, to distinguish static methods from instance methods, many developers (and this book) include the leading class name even when it is not strictly required.

Some classes exist solely to define static methods. Such classes group related functionality together, but objects of the class are never instantiated. For example, the built-in Mouse class exists solely to define the static methods show( ) and hide( ) (used to make the system pointer visible or invisible). Those static methods are accessed through Mouse directly (as in, Mouse.hide( )), not through an instance of the Mouse class. Objects of the mouse class are never created.

Static methods have two limitations that instance methods do not. First, a class method cannot use the this keyword. Second, a static method cannot access the instance variables and instance methods of the class in which it is defined (unlike instance methods, which can access static variables and static methods in addition to instance variables and other instance methods).

In general, static methods are used less frequently than static variables. Our virtual zoo program does not use static methods at all. To demonstrate the use of static methods, let's return to the email validation scenario presented earlier in Chapter 2. In that scenario, we created a loop to detect whether or not an email address contains the @ character. Now let's imagine that our application has grown large enough to warrant the creation of a utility class for working with strings. We'll call the utility class StringUtils. The StringUtils class is not meant to be used to create objects; instead, it is merely a collection of static methods. As an example, we'll define one static method, contains( ), which returns a Boolean value indicating whether a specified string contains a specified character. Here's the code:

public class StringUtils {
  public function contains (string, character) {
    for (var i:int = 0; i <= string.length; i++) {
      if (string.charAt(i) == character) {
        return true;
      }
    }
    return false;
  }
}

The following code shows how our application would use the contains( ) method to check whether an email address contains the @ character:

StringUtils.contains("me@moock.org", "@");

Of course, in a real application, the email address would be supplied by the user and then contains( ) would determine whether or not to submit a form. The following code demonstrates a more realistic situation:

if (StringUtils.contains(userEmail, "@")) {
  // Code here would submit the form
} else {
  // Code here would display an "Invalid data" message to the user
}

In addition to the static methods we create ourselves, ActionScript automatically creates one static method, known as the class initializer, for every class. Let's take a look.

The Class Initializer

When ActionScript defines a class at runtime, it automatically creates a method named the class initializer and executes that method. In this class initializer, ActionScript places all of the class's static variable initializers and all class-level code that is not a variable definition or a method definition.

The class initializer offers an opportunity to perform one-time setup tasks when a class is defined, perhaps by invoking methods or accessing variables that are external to the current class. For example, suppose we're creating an email reader application, and we want its visual appearance to match the operating system's graphical style. To determine which graphical theme the mail reader should use, the application's main class, MailReader, checks the current operating system in its class initializer and sets a corresponding static variable, theme. The theme variable dictates the graphical theme used throughout the application. The following code shows the class initializer for MailReader. To check the operating system, MailReader uses the static variable, os, defined by the built-in flash.system.Capabilities class.

package {
  import flash.system.*;

  public class MailReader {
    static var theme;
    if (Capabilities.os == "MacOS") {
      theme = "MAC";
    } else if (Capabilities.os == "Linux") {
      theme = "LINUX";
    } else {
      theme = "WINDOWS";
    }
  }
}

Code in the class initializer runs in interpreted mode, and is not compiled by the JIT compiler. Because JIT-compiled code generally executes much more quickly than interpreted code, you should consider moving processor-intensive code out of the class initializer when performance is a priority.

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