Essential Actionscript 2.0 - by colin moock collected by Jimbob


MY RESOURCES | Chapter2 | Chapter6 | Chapter12 | example files

Chapter 2. Object-Oriented ActionScript

Colin Moock


Note: The following chapter is a preview excerpt from O'Reilly's Essential ActionScript 2.0 by Colin Moock. You can purchase the book on the O'Reilly website.

Ironically, Flash users who are new to object-oriented programming (OOP) are often familiar with many object-oriented concepts without knowing their formal names. This chapter demystifies some of the terminology and brings newer programmers up to speed on key OOP concepts. It also serves as a high-level overview of OOP in Flash for experienced programmers who are making their first foray into Flash development.

Requirements

While Flash MX Professional 2004 is not required for this article, it is recommended:

Procedural Programming and Object-Oriented Programming

Traditional programming consists of various instructions grouped into procedures. Procedures perform some task without any knowledge of or concern for the larger program. For example, a procedure might perform a calculation and return the result. In a procedural-style Flash program, repeated tasks are stored in functions and data is stored in variables. The program runs by executing functions and changing variable values, typically for the purpose of handling input and generating output. Procedural programming is sensible for certain applications; however, as applications become larger or more complex and the interactions between procedures (and the programmers who use them) become more numerous, procedural programs can become unwieldy. They can be hard to maintain, hard to debug, and hard to upgrade.

Object-oriented programming (OOP) is a different approach to programming, intended to solve some of the development and maintenance problems commonly associated with large procedural programs. OOP is designed to make complex applications more manageable by breaking them down into self-contained, interacting modules. OOP lets us translate abstract concepts and tangible real-world things into corresponding parts of a program (the “objects” of OOP). It’s also designed to let an application create and manage more than one of something, as is often required by user interfaces. For example, we might need 20 cars in a simulation, 2 players in a game, or 4 checkboxes in a fill-in form.

Properly applied, OOP adds a level of conceptual organization to a program. It groups related functions and variables together into separate classes, each of which is a self-contained part of the program with its own responsibilities. Classes are used to create individual objects that execute functions and set variables on one another, producing the program’s behavior. Organizing the code into classes makes it easier to create a program that maps well to real-world problems with real-world components. Parts II and III of this book cover some of the common situations you’ll encounter in ActionScript and show how to apply OOP solutions to them. But before we explore applied situations, let’s briefly consider the basic concepts of OOP.

Key Object-Oriented Programming Concepts

An object is a self-contained software module that contains related functions (called its methods) and variables (called its properties). Individual objects are created from classes, which provide the blueprint for an object’s methods and properties. That is, a class is the template from which an object is made. Classes can represent theoretical concepts, such as a timer, or physical entities in a program, such as a pull-down menu or a spaceship. A single class can be used to generate any number of objects, each with the same general structure, somewhat as a single recipe can be used to bake any number of muffins. For example, an OOP space fighting game might have 20 individual SpaceShip objects on screen at one time, all created from a single SpaceShip class. Similarly, the game might have one 2dVector class that represents a mathematical vector but thousands of 2dVector objects in the game.

The term instance is often used as a synonym for object. For example, the phrases “Make a new SpaceShip instance” and “Make a new SpaceShip object” mean the same thing. Creating a new object from a class is sometimes called instantiation.

To build an object-oriented program, we:

What the objects do determines the behavior of the program.

In addition to using the classes we create, a program can use any of the classes built into the Flash Player. For example, a program can use the built-in Sound class to create Sound objects. An individual Sound object represents and controls a single sound or a group of sounds. Its setVolume( ) method can raise or lower the volume of a sound. Its loadSound( ) method can retrieve and play an MP3 sound file. And its duration property can tell us the length of the loaded sound, in milliseconds. Together, the built-in classes and our custom classes form the basic building blocks of all OOP applications in Flash.

Class Syntax

Let’s jump right into a tangible example. Earlier, we suggested that a space fighting game would have a SpaceShip class. The ActionScript that defines the class might look like the source code shown in Example 2-1 (don’t worry if much of this code is new to you; we’ll study it in detail in the coming chapters).

Example 2-1. The SpaceShip class

class SpaceShip {
  // This is a public property called speed.
  public var speed:Number;

  // This is a private property called damage.
  private var damage:Number;

  // This is a constructor function, which initializes 
  // each SpaceShip instance.
  public function SpaceShip () {
    speed = 100;
    damage = 0;
  }

  // This is a public method called fireMissile().
  public function fireMissile ():Void {
    // Code that fires a missile goes here.
  }

  // This is a public method called thrust().
  public function thrust ():Void {
    // Code that propels the ship goes here.
  }
}

Notice how the SpaceShip class groups related aspects of the program neatly together (as do all classes). Variables (properties), such as speed and damage, related to spaceships are grouped with functions (methods) used to move a spaceship and fire its weapons. Other aspects of the program, such as keeping score and drawing the background graphics can be kept separate, in their own classes (not shown in this example).

Object Creation

Objects are created (instantiated) with the new operator, as in:

new ClassName()

where ClassName is the name of the class from which the object will be created.

For example, when we want to create a new SpaceShip object in our hypothetical game, we use this code:

new SpaceShip()

The syntax for creating objects (e.g., new SpaceShip( )) is the same in ActionScript 2.0 as it was in ActionScript 1.0. However, the syntax for defining classes in ActionScript 2.0 differs from ActionScript 1.0.

Most objects are stored somewhere after they’re created so that they can be used later in the program. For example, we might store a SpaceShip instance in a variable named ship, like this:

var ship:SpaceShip = new SpaceShip();

Each object is a discrete data value that can be stored in a variable, an array element, or even a property of another object. For example, if you create 20 alien spaceships, you would ordinarily store references to the 20 SpaceShip objects in a single array. This allows you to easily manipulate multiple objects by cycling through the array and, say, invoking a method of the SpaceShip class on each object.

Object Usage

An object’s methods provide its capabilities (i.e., behaviors)—things like “fire missile,” “move,” and “scroll down.” An object’s properties store its data, which describes its state at any given point in time. For example, at a particular point in a game, our ship’s current state might be speed is 300, damage is 14.

Methods and properties that are defined as public by an object’s class can be accessed from anywhere in a program. By contrast, methods and properties defined as private can be used only within the source code of the class or its subclasses. As we’ll learn in Chapter 4, methods and properties should be defined as public only if they must be accessed externally.

To invoke a method, we use the dot operator (i.e., a period) and the function call operator (i.e., parentheses). For example:

// Invoke the ship object's fireMissile() method. ship.fireMissile();

To set a property, we use the dot operator and an equals sign. For example:

// Set the ship's speed property to 120. ship.speed = 120;

To retrieve a property’s value, we use the dot operator on its own. For example:

// Display the value of the speed property in the Output panel. trace(ship.speed);

Encapsulation

Objects are said to encapsulate their property values and method source code from the rest of the program. If properly designed, an object’s private properties and the internal code used in its methods (including public methods) are its own business; they can change without necessitating changes in the rest of the program. As long as the method names (and their parameters and return values) stay the same, the rest of the program can continue to use the object without being rewritten.

Encapsulation is an important aspect of object-oriented design because it allows different programmers to work on different classes independently. As long as they agree on the names of the public methods through which they’ll communicate, the classes can be developed independently. Furthermore, by developing a specification that shows the publicly available methods, the parameters they require, and the values they return, a class can be tested thoroughly before being deployed. The same test code can be used to reverify the class’s operation even if the code within the class is refactored (i.e., rewritten to enhance performance or to simplify the source code without changing the previously existing functionality).

In Chapter 4, we’ll learn how to use the private modifier to prevent a method or property from being accessed by other parts of a program.

Datatypes

Each class in an object-oriented program can be thought of as defining a unique kind of data, which is formally represented as a datatype in the program.

A class effectively defines a custom datatype.

You are probably already familiar with custom datatypes defined by built-in ActionScript classes, such as the Date class. That is, when you create a Date object using new Date( ), the returned value contains not a string or a number but a complex datatype that defines a particular day of a particular year. As such, the Date datatype supports various properties and methods uniquely associated with dates.

Datatypes are used to impose limits on what can be stored in a variable, used as a parameter, or passed as a return value. For example, when we defined the speed property earlier, we also specified its datatype as Number (as shown in bold):

// The expression ":Number" defines speed's datatype. public var speed:Number;

Attempts to store a non-numeric value in the speed property generate a compile-time error.

If you test a movie and Flash’s Output panel displays an error containing the phrase “Type mismatch,” you know that you used the wrong kind of data somewhere in your program (the compiler will tell you precisely where). Datatypes help us guarantee that a program isn’t used in unintended ways. For example, by specifying that the datatype of speed is a number, we prevent someone from unintentionally setting speed to, say, the string “very fast.” The following code generates a compile-time error due to the datatype mismatch:

public var speed:Number = "very fast";  // Error! 
                                        // You can’t assign a String to a
                                        // variable whose type is Number.

We’ll talk more about datatypes and type mismatches in Chapter 3.

Inheritance

When developing an object-oriented application, we can use inheritance to allow one class to adopt the method and property definitions of another. Using inheritance, we can structure an application hierarchically so that many classes can reuse the features of a single class. For example, specific Car, Boat, and Plane classes could reuse the features of a generic Vehicle class, thus reducing redundancy in the application. Less redundancy means less code to write and test. Furthermore, it makes code easier to change—for example, updating a movement algorithm in a single class is easier and less error prone than updating it across several classes.

A class that inherits properties and methods from another class is called a subclass. The class from which a subclass inherits properties and methods is called the subclass’s superclass. Naturally, a subclass can define its own properties and methods in addition to those it inherits from its superclass. A single superclass can have more than one subclass, but a single subclass can have only one superclass (although it can also inherit from its superclass’s superclass, if any). We’ll cover inheritance in detail in Chapter 6.

Packages

In a large application, we can create packages to contain groups of classes. A package lets us organize classes into logical groups and prevents naming conflicts between classes. This is particularly useful when components and third-party class libraries are involved. For example, Flash MX 2004’s GUI components, including one named Button, reside in a package named mx.controls. The GUI component class named Button would be confused with Flash’s built-in Button class if it weren’t identified as part of the mx.controls package. Physically, packages are directories that are collections of class files (i.e., collections of .as files).

We’ll learn about preventing naming conflicts by referring to classes within a package, and much more, in Chapter 9.

Compilation

When an OOP application is exported as a Flash movie (i.e., a .swf file), each class is compiled; that is, the compiler attempts to convert each class from source code to bytecode—instructions that the Flash Player can understand and execute. If a class contains errors, compilation fails and the Flash compiler displays the errors in the Output panel in the Flash authoring tool. The error messages, such as the datatype mismatch error described earlier, should help you diagnose and solve the problem. Even if the movie compiles successfully, errors may still occur while a program is running; these are called runtime errors. We’ll learn about Player-generated runtime errors and program-generated runtime errors in Chapter 10.

Starting an Objected-Oriented Application

In our brief overview of OOP in Flash, we’ve seen that an object-oriented application is made up of classes and objects. But we haven’t learned how to actually start the application running. Every Flash application, no matter how many classes or external assets it contains, starts life as a single .swf file loaded into the Flash Player. When the Flash Player loads a new .swf file, it executes the actions on frame 1 and then displays the contents of frame 1.

Hence, in the simplest case, we can create an object-oriented Flash application and start it as follows:

  1. Create one or more classes in .as files.
  2. Create a .fla file.
  3. On frame 1 of the .fla file, add code that creates an object of a class.
  4. Optionally invoke a method on the object to start the application.
  5. Export a .swf file from the .fla file.
  6. Load the .swf file into the Flash Player.

We’ll study more complex ways to structure and run object-oriented Flash applications in Chapters 5, 11, and 12.

About the author

Colin Moock is an independent web guru with a passion for networked creativity and expression. He is author of the world-renowned guides to Flash programming, ActionScript for Flash MX: The Definitive Guide (O’Reilly & Associates, 2003, 2001) and Essential ActionScript 2.0 (O’Reilly Media, Inc., 2004). A web professional since 1995, Moock runs one of the web's most venerable Flash developer sites, www.moock.org. He spends most of his time pursuing his cardinal interest, multiuser application development, and working on Unity, moock.org's complete commercial framework for creating and deploying multiuser applications for Macromedia Flash.

 


Chapter2 | Chapter6 | Chapter12 | example files
collected by Jimbob 2006.03