AS2 OOP: Class Structure
         by senocular  

Properties and Methods
A class block contains the entire definition for that class. This not only includes the constructor itself, but, more obviously, properties and methods needed for that class.

Properties in a class are declared in the class block along with the constructor. In declaring the properties, you're letting the class know which properties instances will have and be able to use in the constructor and/or their methods. When doing this, you will need to make sure that you use the var keyword. The following is an example of a Person class with two properties, name and age. The name property has an initial value of "none" while age is simply undefined to start. Giving them a definition there is optional. Both are defined in the constructor based on arguments passed, though again, that isn't required.

class Person {
var name:String = "none";
var age:Number;
 
function Person(n:String, a:Number) {
name = n;
age = a;
}
}

Look closely at the Person constructor and its use of name and age. Neither have the this prefix as was necessary with ActionScript 1.0. With ActionScript 2.0, the this isn't necessary. You can use it if you want, though a direct reference to the variable name will also work. Because of that behavior, you will want to be careful not to use parameters in your constructor and class methods that have the same name as the properties within that class or there may be confusion between the two. If you do use similar names, you will need to use this to distinguish properties from arguments. Lets look at an ActionScript 1.0 version of this class.

/* Actionscript 1.0 */
Person = function(name, age) {
this.name = name;
this.age = age;
}

Here, in ActionScript 1.0, this is required for the constructor. Not only does it differentiate between properties and arguments, but it is needed to specifically assign name and age to the instance being created. That is not necessary in an ActionScript 2.0 class.

What about methods? They too are defined in the class body just as are properties. Remember, methods need to stick to the function [name]() format of function definition.

class Person {
var name:String = "none";
var age:Number;
 
function Person(n:String, a:Number) {
name = n;
age = a;
}
 
function haveBirthday():Array {
var spankings = new Array(age);
return spankings;
}
}

A haveBirthday method was added to our Person class. It creates an array with the length based on the person instance's age and returns it. Notice the strictly typed Array return value for the method indicating that an array is returned. If nothing is returned, Void would be used. In the constructor, nothing is technically returned but a Void was also not specified as a return type. Being the special function that the constructor is, it is not allowed a return type of any kind, so don't attempt to give it one. Using strict typing in constructor parameters, however, is acceptable.

Also, in haveBirthday, a new var is created, spankings. This variable is not the same as those declared at the top of the class. Variables created with var in the constructor or methods are simply local variables that exist within the context of that function call. They aren't given to the class instance and will not remain after the call of the function has completed.

 Advanced Programmers Note: Overloading
Flash never has and still does not, even with ActionScript 2.0, support method overloading. If you need or desire this functionality, the best alternative is to create a 'smart' method which will examine the arguments array object passed in a method call and behave accordingly based on that, either by checking its length or by evaluating variable instanceof's - whatever is necessary to determine which course of action (or alternate method) is to be taken.

As you can see, methods in ActionScript 2.0 bear absolutely no reference to the prototype object as they did in ActionScript 1.0. In fact, with ActionScript 2.0, you'll never (probably) need to access that confusing prototype object directly at all. Technically, the method is still defined in the prototype, you just don't see it. In fact, the class code block itself is basically a big alias for the class prototype. Aside from the constructor (and static properties and methods) everything within the class code block is added to that classes prototype. Yes, this includes the properties too. Here's a real representation of what the Person class now looks like in ActionScript 1.0

/* Actionscript 1.0 */
Person = function(n, a) {
this.name = n;
this.age = a;
};
 
Person.prototype.name = "none";
Person.prototype.age = undefined;
 
Person.prototype.haveBirthday = function() {
var spankings = new Array(this.age);
return spankings;
};

The properties defined for the class are not defined specifically for instances when they are created, but are instead added to the prototype object as shared properties for all instances created. They become specific to the instance when defined within the constructor (or some other method if not handled through the constructor specifically).

This is a very important concept to understand when dealing with object and array properties. Because they are assigned to the prototype and not instances, you will need to specifically define the property within the constructor of the class or else methods of that class would be accessing the common object or array within the prototype. Here's an example where a single array property gets used by two instances.

// in HighScores.as
class HighScores {
var scores:Array = new Array();
 
function HighScores(score) {
scores.push(score);
}
 
function getScores():String {
return scores.join(", ");
}
}
// in Flash movie
var scoresList1:HighScores = new HighScores(100);
trace(scoresList1.getScores()); // 100
 
var scoresList2:HighScores = new HighScores(50);
trace(scoresList2.getScores()); // 100, 50

You can see that both instances of HighScores, scoresList1 and scoresList2, used the same scores array in their constructor. This was because a unique property for that array was not created for each. When not, that default prototype value specified in the class body is used. To prevent this, just be sure to redefine your unique objects and arrays within your constructor. You won't have to do this with all variables since its perfectly fine to have a number or string referenced in this shared way. It only effects properties which are other objects themselves. Here's the fix for HighScores.

class HighScores {
var scores:Array = new Array();
 
function HighScores(score) {
// assign unique property in constructor
scores = new Array();
scores.push(score);
}
 
function getScores():String {
return scores.join(", ");
}
}

Now what if you actually want properties to be consistent throughout all instances? Then we'd use a static property (or static method for that matter).

 




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.