
Photo by Neeku.
AS3 enforces the ideas of Object Oriented Programming (OOP) a lot more than AS2 ever did. One of the fundamental concepts of OOP is inheritance, allowing classes to take the properties and methods of other classes and build upon them further.
In this post, I’ll explain the three most important keywords for using class inheritance in AS3: extends, override and super.
An Example: MovieClip
Let’s take a look at the MovieClip class to see an example of inheritance at work. If you check out the LiveDocs for this class, you’ll see this line in the description:
Inheritance: MovieClip -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object
The arrows simply mean “inherits from”, so MovieClip inherits from Sprite, which in turn inherits from DisplayObjectContainer, and so on, right down to Object.
The Object class is extremely basic, containing just a handful of properties and methods. It’s an empty shell, but because it allows for the possibility of properties and functions to be added, it’s an excellent base for more complex classes.
The EventDispatcher class builds upon Object by adding event-related methods (functions), like addEventListener() and dispatchEvent().
Now, because DisplayObject inherits from EventDispatcher, it also contains addEventListener(), dispatchEvent(), and so on. It then builds upon this by adding methods, properties, and interfaces that allow instances to be displayed on screen — for example, x and y properties for positioning, and the hitTestObject() method for checking for overlaps.
The InteractiveObject class allows for user interaction, adding properties like mouseEnabled and tabIndex, and events like click and keyDown.
Then we have the DisplayObjectContainer class, which can contain other DisplayObjects (and descendents of DisplayObject, like InteractiveObject and DisplayObjectContainer) with methods like addChild().
The Sprite class adds, among other things, the graphics property, which itself is an instance of the Graphics class that allows for the drawing of vector shapes within the object. So the Sprite adds vector drawing capability, and some miscellaneous interface features.
Finally we reach the MovieClip class, whose main addition is that of a timeline, allowing for animation. Therefore, it has methods like nextFrame(), play() and goToAndStop(), and properties like currentFrame and totalFrame.
If you want the full details of what each class does, take a look at their corresponding LiveDocs page, and turn off “Show Inherited Public Properties/Methods”.
So that’s a concrete example of how Flash uses inheritance to structure its own classes. How can we use it?
Extends
One thing that bugs me about the MovieClip class is that, if it’s on the last frame and I call nextFrame(), it stays on the last frame. I’d much prefer it to go back to the first frame, to make it easier to loop.
Rather than just complaining, let’s make our own class, LoopingMovieClip, that has this feature.
We’ll need to use the extends keyword for this. Create a new class file like so:
1 2 3 4 5 6 7 8 9 10 11 12 | package { import flash.display.MovieClip; public class LoopingMovieClip extends MovieClip { public function LoopingMovieClip() { } } } |
By writing extends MovieClip in line 5 (and importing the MovieClip class in line 3), our new class inherits every public (or protected — more on that here) method and property. Of course, this means that at the minute LoopingMovieClip has no functionality other than that which MovieClip already has.
I’m going to add a new function, nextFrameOrLoopToFirst(), that’ll do what I want:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package { import flash.display.MovieClip; public class LoopingMovieClip extends MovieClip { public function LoopingMovieClip() { } public function nextFrameOrLoopToFirst():void { if ( currentFrame == totalFrames ) { gotoAndStop( 1 ); } else { gotoAndStop( currentFrame + 1 ); } } } } |
Very simple. If you want to test it out in the Flash IDE, just create a new movie clip symbol as usual, right-click it in the library, select Properties, export it for ActionScript, and set its Base class to LoopingMovieClip. You can give its class any name you want, and it’ll inherit from the base class. Now add a few frames to the symbol, and try running our new function.
It works, but wouldn’t it be better if we could make the nextFrame() method itself do this?
Override
If you try to do the same as before, but call the function nextFrame() instead of nextFrameOrLoopToFirst(), like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package { import flash.display.MovieClip; public class LoopingMovieClip extends MovieClip { public function LoopingMovieClip() { } public function nextFrame():void { if ( currentFrame == totalFrames ) { gotoAndStop( 1 ); } else { gotoAndStop( currentFrame + 1 ); } } } } |
…you’ll get the following error:
1024: Overriding a function that is not marked for override.
This is telling us that nextFrame() is already a function in one of the classes that LoopingMovieClip inherits from (and therefore in LoopingMovieClip itself), and we can’t have two functions with the same name. You will probably have guessed that we can use the override keyword to get around this. Change your function like so:
12 13 14 15 16 17 18 19 20 21 22 | override public function nextFrame():void { if ( currentFrame == totalFrames ) { gotoAndStop( 1 ); } else { gotoAndStop( currentFrame + 1 ); } } |
By adding the override keyword, we’ve told Flash that we’re aware of the inherited nextFrame() function, but we’d like to replace it with our own. If you test it out now, you’ll see we don’t get any errors, and that our nextFrame() function acts just like our nextFrameOrLoopToFirst() function did before.
One thing to bear in mind here is that we need to match the “signature” of the function that we are overriding — i.e., whether it’s public or protected, the parameters it accepts, and the type of variable it returns.
For example, we might like to add an optional parameter to the function that allows it to be backwards-compatible:
12 13 14 15 16 17 18 19 20 21 22 | override public function nextFrame( p_loop:Boolean = false ):void { if ( ( p_loop ) && ( currentFrame == totalFrames ) ) { gotoAndStop( 1 ); } else { gotoAndStop( currentFrame + 1 ); } } |
The idea here is that calling nextFrame() will not cause any looping, so our existing code will act the same with LoopingMovieClips as it did with MovieClips. Trouble is, when we test this, this error occurs:
1023: Incompatible override.
In other words, because we changed the signature of our function (in this case by altering the parameters allowed), it’s no longer identical to the original and so can’t override it. Watch out for this.
Next, let’s tackle gotoAndStop(). If I call gotoAndStop( 7 ) on a 5-frame movie clip, I’d like it to go to frame 2. Sounds simple, but there’s a snag…
Super
In theory this should be similar to what we did before. Start by defining the function:
24 25 26 27 | override public function gotoAndStop( frame:Object, scene:String = null ):void { } |
(FlashDevelop tells me the signature, but you can look it up in the LiveDocs.)
To work out which frame we actually want, we can use the modulo operator, represented by a percentage sign %. This is like division, but it gives us the remainder of the expression.
If you’re rusty on remainders, here’s a quick recap.
- 7 = ( 5 * 1 ) + 2, so 7 divided by 5 is 1 remainder 2, and 7 % 5 = 2
- 14 = ( 5 * 2 ) + 4, so 14 divided by 5 is 2 remainder 4, and 14 % 5 = 4
- 20 = ( 5 * 4 ) + 0, so 20 divided by 5 is 4 remainder 0, and 20 % 5 = 0
- 126 = ( 5 * 25 ) + 1, so 126 divided by 5 is 25 remainder 1, and 126 % 5 = 1
- 3 = ( 5 * 0 ) + 3, so 3 divided by 5 is 0 remainder 3, and 3 % 5 = 3
So if we call gotoAndStop( someFrame ) the frame we want to actually go to is someFrame % totalFrames. (Well, unless the result is zero — in that case, we want to go to totalFrames, but let’s ignore this detail for now.)
When we try to put this in, however, there’s a problem:
24 25 26 27 28 29 | override public function gotoAndStop( frame:Object, scene:String = null ):void { var requestedFrame:int = frame as int; var actualFrame:int = requestedFrame % totalFrames; gotoAndStop( actualFrame ) } |
(Line 26 isn’t a real problem; Flash expects the frame to be input as an Object rather than an int — most likely so that we can pass a frame label through as a String, as RedRail points out — so here we convert the frame parameter to an int so that we can use the modulo operator on it.)
In line 28 we need to call gotoAndStop(), but… we’ve already overriden it! What we need to call is the original gotoAndStop() method, the one defined by MovieClip. This is where super comes in.
The super keyword allows us to access the methods and functions of the inherited class. It’s used like this:
24 25 26 27 28 29 | override public function gotoAndStop( frame:Object, scene:String = null ):void { var requestedFrame:int = frame as int; var actualFrame:int = requestedFrame % totalFrames; super.gotoAndStop( actualFrame ) } |
Also, the constructor function — the function with the same name as the class that is run when an instance of that class is created — acts like an automatically overridden function, in the sense that the constructor of the inherited class can be accessed using super. To do this, just call super(), rather than super.constructor() or super.MovieClip() or whatever. Remember to make sure the list of parameters match!
Wrapping Up
Admittedly the functions we’ve created here could do with some improvement. Calling gotoAndStop( 5 ) on a five-frame movie clip will actually attempt to go to frame #0 with the code I’ve written, so be sure to change that if you want to use this in a real project. Also, nextFrame() could just call gotoAndStop( currentFrame + 1 ) to simplify things, and you might want to add prevFrame() and gotoAndPlay() functions. Plus, gotoAndStop() needs to be edited to handle frame labels and scenes. It’s a work in progress
Hopefully you find the actual concepts clear, though
If you’ve any questions, please post them in the comments.

{ 22 comments… read them below or add one }
Hi, Nice blog post, I enjoyed reading it.
I’m quite new to Flash CS4 and AS3 myself. I have to say I really do enjoy learning it. I remember Flash 5..ahh the good old days.
You can use frame label rather than frame number in goto functions, so that’s probably why input must be an object. I’d add something like if(frame is int) to prevent unexpected behaviour when a frame label is passed.
Hey David, glad you enjoyed it.
Can’t say I have fond memories of AS1 though
I started with Flash 5
Thanks for explaining that, RedRail! I’ve added your tip to the main post.
Very nice Michael. Finally I got it right
Once again a very helpful blog post. Just begun restructuring my project with OOP in mind and it really helped in clearing up some of the things I wondered about the keywords.
Coming from an OOP intensive programming language, I find the inheritance structure of AS3 really neat. The only downside that I see is that it only has the ability to inherit from 1 class at a time. Kinda like stacking a tower.
Thanks guys
@Kronosfere I used to feel the same way, but after talking to Nick Wiggill from Visual Harmonics I changed my mind
He wrote a great post on the subject here, and another on how to actually do this in AS3 here.
Another great set of articles on the subject (though not specifically for AS3) is here, from RiverMan Media.
…and I was just reading about the new PushButton Engine which uses components too.
Hmm.. That was a really interesting read there, thanks for the link. It really opens up another way to code in AS3. =D
Very usefull post. Thank you!
Thank you both!
Please confirm your statement that “super.super.super.addChild()” is valid. As far as I know it is not possible to nest the super keyword like this: super.super
You’re right, you can’t. Sorry, that was sloppy of me. I’ve removed that from the post now, thanks for pointing it out.
Cant we do it simply like below.. That works fine when i tested.
override public function gotoAndStop( frame:Object, scene:String = null ):void { //var requestedFrame:int = frame as int; //var actualFrame:int = requestedFrame % totalFrames; super.gotoAndStop( frame ); }@Asif: That’ll work, but it doesn’t add any extra functionality; it just calls the regular method. In fact, it removes functionality, because the
sceneparameter is now ignored.Hello, i was looking around in the web regarding the importance of “override” in AS3.0 however to my understanding the keyword “override” simply a way to offer name usage of existing e.g nextFrame() instead of the long nextFrameOrLoopToFirst() or does it have any more usage than this please enlighten me and sorry for the noob question
Hey Scarlight,
Yep, you’ve got it! But remember, other classes might be calling e.g. nextFrame() already, expecting it to do one thing — by overriding it, you can change what happens without having to make those other classes call nextFrameOrLoopToFirst() instead.
That might be a good thing, or it might be a terrible thing. Depends how you use it
myMovieClip = new LoopingMovieClip()
LoopingMovieClip.NextFrame() // uses the custom function
superClip = new MovieClip()
superClip.NextFrame() // somehow , by magic, ALSO uses the custom function.
is this possible, or am i missing the OOPoint?
thanks,
D
Michael, please disregard the last post, somehow I deleted the top half as I sent it… here’s the full question
Hi Michael, thanks for the post, it’s made a few lightbulbs go off….
I was wondering if this is possible :
Are you able to specify that objects created from the superclass ALSO use the modified functions of a subclass? e.g, in your example I assume that
superClip = new MovieClip()
superClip.NextFrame() // uses it's own, 'default' function
Is there a way to do the following??
superClip = new MovieClip()
superClip.NextFrame() // somehow , by magic, ALSO uses the custom function.
is this possible, or am i missing the OOPoint?
thanks,
D
Hey UnkleDave,
Hmm. No, I don’t know of a way to do that. Why would you like to?
Excellent!!! Heaving read too many books on AS3, I finally understood the concepts of extends, override and super from your tutorial. Waiting for more…
Thanks for this very clear explanation of something I’ve been wondering about. Well done!
Hey fakeartist, hey Ian — thanks very much! I’m very happy to hear that