What is super 


The keyword "super" appears in Flash MX.

There are two syntax for it. One is super(args). The other is super.method(args).

From the syntax "super(args)", it seems to be a function. But, no ! We can not implement Function.apply(obj, arguments) to it. If it is a function, trace(super) should reveal [function Object]. But it reveals "undefined".

From the syntax "super.method(args)", we expect it to be an object similar to "this". But trace(super) reveals no [object Object]. The output is "undefined".

So, what is it ? 


super(args)

Before the era of super(arg)

A constructor may have parameters. It initiates values by the values supplied through parameters.

superClass=function(x){
    this.x=x;
}

OR

superClass=function(x){
    this.init(x);
}
superClass.prototype.init=function(x){this.x=x;}

If we subClass this superClass and inherit the initiation process, we need a way to pass the parametes in to initiate values.

subClass=function(x){
//how to script the initiation done by super constructor ?
}
subClass.prototype=new superClass();

Of course, we can copy and paste the codes from superClass to subClass: this.x=x or this.init(x); to initiate it. That is not very elegant in the view of OOP inheritance.

How about: subClass.prototype=new superClass(x); ?

No ! We are not defining a function here. We are creating an instance of superClass here. The x must be specified and feed with a real value.

How about: this=new C(x); ?

No. We can not assign reference to this. "this" should be treat as read only.

The work around is to turn superClass constructor as a method of subClass and implement this method.

subClass=function(x){
this.temp=superClass;
        this.temp(x);
        delete this.temp;
}
subClass.prototype=new superClass();

This will successfully setting this.x=x; or executing the this.init(x) method.

That is the era of Flash 5.

In era of Flash MX, we have the tool: super();


How to know which is super

"super(args)" is "to find the __constructor__ in its prototype object then execute it as a method.

The searching for __constructor__ is done dynamically when super() is called. Becareful, not every object has __constructor__ property. Only those objects created by constructor has __constructor__ property. Only instances of a Class has the __constructor__ property.

subClass=function(x){
super(x)
}
subClass.prototype=new superClass();


Super() start to search __constructor__ through subClass.prototype. The prototype is an instance of superClass created by "new-constructor". So, we find the __constructor__ to be the function "superClass". Then it executes superClass(x) as a method; The result is setting this.x=5;

Note: super() does not need to be at the first line of constructor. super() does not have the same effect as new. It will not reset everything like "new". 


subClass.prototype.__proto__=superClass.prototype

Some may argue about the syntax for inheritance suggested by macromedia. So we meet the syntax:

subClass.prototype.__proto__=superClass.prototype;

Here, the prototype of subClass is not an instance of superClass anymore. It is not created by "new-constructor" . It does not have __constructor__ property. Flash will search through the __proto__ chain and reach the superClass.prototype. Well, we intend to find __constructor__ in subClass.prototype, now we are searching in superClass.prototype. It is weird. If all our inheritance adopt such syntax, we end up with search super-super-superClass.prototype endlessly.

To solve it, we assign a constructor property to subClass.prototype like this:

subClass.prototype.__constructor__=superClass;

Thus, super(x) will execute superClass(x);

Macromedia does not recommand this. They suggest __proto__ should be read only.

In addition, the __constructor__ property is hidden and undocumented.

The third, arbituraily supplying  __constructor__  to an object not an instance of that Class is somewhat not "natural".


super.method(args)

To extend the functionality of the methods inherited from superClass

superClass.prototype.moveRight=function(dx){
    this._x+=dx;
}

Now we would like our subClass.prototype.moveRight inherits that action but also setting a flag when it moves.

So here is the script:

subClass.prototype=new superClass();
subClass.prototype.moveRight=function(dx){
    this.temp=superClass.prototype.moveRight;
    this.temp(dx);
    delete this.temp;
    this.direction="Right";
}

In the era of Flash MX, we can simply use the syntax of super.method(args);

subClass.prototype=new superClass();
subClass.prototype.moveRight=function(dx){
    super.moveRight(dx);
    this.direction="Right";
}

So, how Flash find the super.method(args)

It first searchs up to resolve what is the super constructor (like super()). Then it tries to find the methods in the prototype of super constructor. If not found, it search through __proto__ chain.

It is the method in super constructor.prototype. It is the methods defined in the prototype of superClass.

The method defined in Constructor

What if we define a method in the body of super constructor ?

superClass=function(){
    this.moveLeft=function(){this._x-=5;}
}
superClass.prototype.moveRight=function(){this._x+=5;}

When we subClass it, we refer that moveRight method by super.moveRight(). But , can we refer  that "moveLeft" method as super.moveLeft() ?

NO !

The method in Prototype is belong to the prototype object and is available. The methods defined in constructor is only a "definition" not yet a true callable method.

So:

1. Every instances of superClass has the moveLeft method but it is not the super.moveLeft method.

2. If we call super() in subClass, a moveLeft method will be created in local of subClass. That will mask moveLeft method defined in prototype if any.

3. Macromedia suggests that to define a method in constructor is a bad idea.
     (from  actionscript_standards.pdf of macromedia site)


super.property

superClass.prototype.styleTable=[];

When I do subClass, can I refer that styleTable as super.styleTable ?

No. There is no such syntax for keyword "super".


Can I assign super ?

subClass=function(x){
    this.super=superClass;
    this.super(x);
}
subClass.prototype=new superClass();

That script works. However, the "super" in that script is just a custom variable name. It is completely different from what we expect from the keyword "super"; Real "super" is not a function nor an object.

Correct syntax is super(args) or super.method(args). Please note the syntax: it is not "this.super(args)" or "this.super.method(args);