|
|
|
Super - The Running of the Constructors
After the extends function, running the constructors should be a walk
in the park on a sunny day. We essentially must do two things. Pass
arguments up to the constructors that need them, and then run the constructors
from top down. The only thing that makes this tricky is that the constructors
are not naturally related to each other like the prototypes are. So
what we must do is climb the prototype chain, and at each level, jump
back to the constructor.
Once again, it helps to look to other OO languages to see how they
go about this. Java uses a keyword called 'super', which does exactly
what we are wanting, plus a little - so it merits a closer look. In
Java, the 'super' keyword is used to call the parent class's constructor,
with arguments if desired, using the syntax super(arg0,
arg1, ...). The restriction is that it must be the very first
line in every constructor unless omitted, in which case it will be automatically
inserted without arguments. Instead of deleting itself when it is finished
running the constructors, it gets a second shot at life in the form
of a pointer to the parent class. This allows instances to invoke overridden
methods by saying super.xxx( ).
The good news is we can have all that Java's 'super' has, in a custom
Actionscript routine - if we are willing to place two small burdens
on the user (and remember, when the user feels pain, we feel nothing).
Burden number one is that they will have to say this.super( ) rather
than just super( ). Instances love the word 'this' when they are talking
about themselves, and looking over a typical program, they do seem to
love talking about themselves (as Oscar Wilde once said, "but enough
about me, what do you think of me?"). In this case they are talking
about their own super routine, so that would be this.super, no easy
way around it. This is a feature - if not for 'this', our Actionscript
'super' routine would be so similar to Java's 'super' that people might
forgetfully try to pass off bouncing heads as animation.
The second burden, is that the user MUST have this.super( ... ) as
the first line in every constructor. Well, we aren't magic, but there
are ways to check if a constructor has a 'super' call or not, and insert
one if needed. Unfortunatly all of these involve running the constructor,
which may skew things like a static variable that keeps track of how
many instances have been created. So we'll "make the user pay!",
and demand that they put 'this.super( )' as the first line of every
constructor. Will it throw an error if they don't (like Java does)?
Well, not right off the bat, he he. You have to be a heartless bastard
to write general purpose libraries in Actionscript, never forget that.
So here is the routine. It passes the arguments up the constructor
chain, and then runs the constructors in order from top down. Once it
is done, it changes 'super' to mean parent.prototype, like Java does
- so you can access an overridden property or method by saying this.super.xxx(
). See if you can follow it. (I almost can, but then again, I wrote
it!). TODO: explain this a wee bit better ; ).
Object.customKeyword.prototype.super = function()
{
var count = Object.customKeyword.prototype.super.prototype.cnt++;
var fn = this.__proto__.__proto__;
while(count-- > 0)
{
fn = fn.__proto__;
}
fn = fn.constructor;
this.$_base = fn;
this.$_base( arguments[0],arguments[1],
arguments[2],arguments[3],
arguments[4],arguments[5],
arguments[6],arguments[7] );
delete this.$_base;
if(fn.prototype.__proto__ == Object.customKeyword.prototype)
{
this.super = this.__proto__.__proto__.prototype;
Object.customKeyword.prototype.super.prototype.cnt = 0;
}
}
.customKeyword.prototype.super.prototype.cnt = 0;
Extend
< < Home >
> Custom
|
|