Super Is (Really) Optional!
Like Java, AS3 has a super() function you can call from your constructor to call your parent class’ constructor. As it turns out, this is more optional than you might think.
The super() function works like this:
class Parent { public function Parent(val:int=0) { trace("Parent constructor got: " + val); } } class Child extends Parent { public function Child() { super(33); trace("Child constructor"); } }
This prints:
Parent constructor got: 33 Child constructor
Unlike C++ or Java, you can move the super() call past the beginning of your constructor:
public function Child() { trace("Child constructor"); super(33); }
And you will predictably get:
Child constructor Parent constructor got: 33
You may also omit the super() call altogether if your parent class’ constructor requires no arguments:
public function Child() { trace("Child constructor"); }
In this case your super() call is implicitly placed at the beginning of your constructor so it as if you typed:
public function Child() { super(); trace("Child constructor"); }
Knowing that, you again get a predictable result:
Parent constructor got: 0 Child constructor
My latest discovery is that you can actually not call your super class’ constructor at all! Check this out:
public function Child() { if (false) { super(); } trace("Child constructor"); }
Since you have a super() call in your function, the compiler will not generate the default super() call at the start of your constructor. You then place the super() call within an impossible-to-reach conditional and it will never be called. The result compiles without warning or error and runs perfectly. It prints this:
Child constructor
Since constructors are a good place to put initialization code, beware that you’re skipping all of what is assumed to have been necessary to instantiate the class. This may be dangerous, so use it only when you’re really sure that the constructor is not relied on.
#1 by Michael Boucher on September 16th, 2009 ·
Unfortunately there is an added side effect to this. Since super is not called the Parent is not instantiated and thus any inherited properties are not set. Take this for instance.
trace:
I am sub: null
From Main: null
#2 by jackson on September 16th, 2009 ·
Yep, I mentioned this in the last paragraph of the article:
It’s definitely a technique for rare circumstances. Actually, I can’t think of much of any reason to ever use it. I really only wrote the article because I accidentally did it while doing some AS3 coding. Your example shows exactly why you want to make sure that your super() call actually gets made. Thanks for the comment!
#3 by Michael Boucher on September 16th, 2009 ·
This is an interesting find though and it appears that functions within Parent still work without the super call.
Nice post and sorry for the ugly code paste above.
#4 by jackson on September 16th, 2009 ·
No problem at all, thank you for the comment. I wrapped your code in the formatting blocks:
<pre lang="actionscript3">
…
</pre>
#5 by ThatSnail on December 19th, 2011 ·
Makes me question the stability of AS3 a little more. Granted, I think it’s bad practice to not inherit the parent’s structure, so I’m not very convinced of the use for this. Still a neat find.
#6 by Oliver on September 7th, 2012 ·
Firstly I’d like to say that I find your articles incredibly inspiring to read, and I recognise that this is an ‘ancient’ article
I could be completely deceived in my thinking, but I reckon the omission of calling super could simplify the concrete class in the decorator pattern, as well as in potentially many other design patterns involving a similar structure of extending a base class plus a has-a (the has-a target avoiding the super call)
I’ll try to make use of this
#7 by Nolan on January 12th, 2013 ·
This clears things up. Thanks!