Make your own free website on Tripod.com

The static elements in AS2 Class


If we want to create many instances of circle with different radius, we create a Circle class. We might expect many properties and methods in this Class.

Expected properties and methods:

function Circle(Rad): the constructor
var radius: the radius of a circle instance.
var shape: "A Circle";
var peerCount: how many Circles have been created.
function dumpInfo(): display shape type , peer count and radius;

So we create a class file:

class Circle {
    function Circle(Radius) {
        radius = Radius;
        peerCount++;
    }
    var radius:Number;
    var shape = "A CIRCLE";
    var peerCount = 0;
    function dumpInfo() {
        trace("shape="+shape);
        trace("peerCount="+peerCount);
        trace("radius="+radius);
    }
}

Lets discuss and do some modification to this class file.

All these methods and properties are by default "public". If we create an instance of this class by: c1=new Circle(5); then we create an instance of Circle with a radius of 5. Also, we attempt to increase the peerCount by 1 when we create an instance.


1.
make radius private

After the circle instance is constructed, we dont want any user change the radius directly by saying "c1.radius=10;" We want radius "readonly through dumpInfo();"

So we try to hide the property "radius" from outside access. We make this property "private" . So, we change the script to "private var radius:Number:"  However, if we test it, the "private" thing does not shield that property well. The code "c1.radius=10;" still works. In AS2, the private thing does not do much help. So, I will focus on the discussion of "static".

2.
make shape static

When we do "trace(c1.shape);", it outputs "A CIRCLE". So, c1 is "A CIRCLE". That works well.

Think about that, although each instance may have different radius, all instance of Circle are likely have the same "shape" as "A CIRCLE". This is a common value to all instances. In other word, if it is an instance of this Circle class, the shape will be "A CIRCLE". We call such property as a "Class property". Usually we dont need a "shape" property for each instance. We store this in the class definition. If we change the shape property form "A CIRCLE" to "A CLOSED UNIFORM ARC", then the dumpInfo will seach in this class definition and display the updated shape data. All instance of Circle including those already created will show the updated shape data on dumpInfo().

Such class method or property is declared as static. Now we make 'static var shape="A CIRCLE"; So, we create c1, c2, c3 from new Circle(). We do c2.dumpInfo, the shape is "A CIRCLE". Then we change it: Circle.shape="A CLOSED UNIFORM ARC". Then when we dumpInfo from c1, c2 or c3 , all of them shows the updated shape data.

Internally, if we declared that property as static, then there is one single value shared by all instances.

3.
static property should be accessed by Class name not instance name.

Wait a minute. Some thing goes wrong then. After I declared the property "shape" as static, my "trace(c1.shape);" output "undefined".

Many language support the access of static property by instance of this Class. We see that the dumpInfo still display the static "shape" well. Why can't we access it by instance ? Is'nt this a character of "private" rather than "static" ?

Anyway, AS2 does not support the access of static property outside of the Class definition by instance. Static methods are said to be "Class methods" rather than "instance methods". So, the correct access of the shape should be "SuperClass.shape". This makes sense but a little bit in-convenient.

In fact, AS2 suggest that, in the code of dumpInfo function, we should use "SuperClass.shape" instead of just "shape".

4.
make peerCount static

Lets check the peerCount property. It is mean to count how many instance we have created. At present we make it a non-static property. This is wrong. Non-static property exists in each instance. So, constructing a new instance only increase the peerCount of that instance its own. So, no matter how many instances we create, each instance shall have a peerCount as 1.

It should be made static. So, there is only one peerCount exists. Thus, each constructing of an instance will try to add 1 to that peerCount. The first instance will make it 1. The second instance will make it 2.

Like the discussion above, it is suggested that we use "SuperClass.peerCount" instead of just "count". Such syntax is very good. It hint us that it is a static property not an instance property.

5.
Will static properties get inherited into subClass ?

Some believe that, static methods belong to that Class they are defined in. We access those methods by ClassName.staticProperty. We should not make it "inherited". That will destroy the meaning of "Class methods".

However, safty means in-convenience. If we can inherit, over-ride other properties, why not to the static properties ?

Think about this condition.

I need to create a class RedCircle extend Circle where I add a static property : "static var colorValue="RED;"  I would like to inherit all those properties and methods of Circle. The dumpInfo should be modified to add an output of color value.

function dumpInfo(){
    trace("colorValue="+colorValue);
    trace("shape="+shape);
    trace("peerCount="+peerCount);
    trace("radius="+radius);
}

I access them the Class definition with the same syntax to colorValue, shape, peerCount and radius be it a private or static of Super class or static of subClass. I did not say Circle.shape or RedCircle.colorValue. Will it work ?

Yes, it works. Those static properties are inherited. So we can access those properties as if they are properties of this class.

Some may favor the syntax like "Circle.shape" and "Circle.peerCount". Such syntax is "object composition" instead of "inheritance".

Here we can see the power of inheritance. 

For comparison, here is the code by composition:

function dumpInfo(){
    trace("colorValue="+RedCircle.colorValue);
    trace("shape="+Circle.shape);
    trace("peerCount="+Circle.peerCount);
    trace("radius="+radius);
}

6.
Access the inherited property by Class Name

For AS2, Some trouble exists here.

If those static properties are inherited then can we access them by "RedCircle.shape" and "RedCircle.peerCount" ? Well, things turn complicated. The answer is partly "yes" and sometimes "no". I would favor "NO".

See the codes below:

trace(Circle);
trace(RedCircle.shape);
trace(RedCircle.peerCount);

The output is:

[type function]
A CIRCLE
0

It seems working. However, if I remove the first line, the folowing 2 trace outputs "undefined".

I dont know the real reason. Some believe that, the Circle class object does not "auto-activated" when we access static methods by this way. But I still dont understand why the instance method dumpInfo of RedCircle can access those static properties well.

7.
to subClass the Math Class

Some one asked about how to extend the Math class which is full of static methods. 

I create a class AdvancedMath extends Math. There I add many new static methods such as "factoria and calculus functions". Naturally, I  want my AdvancedMath owns all the methods of Math. However, all the static methods in Math can not be accessed by Math2 without a mention about "Math".

trace(Math);
a=AdvancedMath.abs(-5);

This works. But if I remove the first line, then AdvancedMath fails to access the abs function that belongs to Math. The mention must be repeated in each script block before I use AdvancedMath. The effect of mentioning wont survive over other script block. 

That make it painful to extends Math class directly.

Well, sure, there are work-arounds. Class is also an Object. Instead of extending the Math class in Class file, I can add a line in frame 1 script:

AdvancedMath.__proto__=Math;

But I always feel regret why those inherited methods can not be accessed directly.


ericlin@ms1.hinet.net