Extends, Override and Super

by Michael James Williams on April 3, 2009 · 35 comments

in AS3 Concepts Explained

Blog post image
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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:

?View Code ACTIONSCRIPT3
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!

Note: if you don’t include a call to super() in your class’s constructor, then Flash will call super() before your constructor is run, anyway – so there’s no getting away from it.

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 :P

Hopefully you find the actual concepts clear, though :) If you’ve any questions, please post them in the comments.

{ 35 comments… read them below or add one }

David April 3, 2009 at 8:43 pm

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. :)

RedRail April 3, 2009 at 9:04 pm

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.

MichaelJWilliams April 3, 2009 at 10:45 pm

Hey David, glad you enjoyed it.
I started with Flash 5 :) Can’t say I have fond memories of AS1 though :P

Thanks for explaining that, RedRail! I’ve added your tip to the main post.

Snurre April 4, 2009 at 10:08 pm

Very nice Michael. Finally I got it right :D

Kronosfere April 6, 2009 at 5:58 am

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.

MichaelJWilliams April 6, 2009 at 12:50 pm

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.

MichaelJWilliams April 6, 2009 at 3:26 pm

…and I was just reading about the new PushButton Engine which uses components too.

Kronosfere April 7, 2009 at 7:11 am

Hmm.. That was a really interesting read there, thanks for the link. It really opens up another way to code in AS3. =D

Social April 20, 2009 at 2:52 pm

Very usefull post. Thank you!

MichaelJWilliams April 20, 2009 at 11:35 pm

Thank you both!

Ephraim June 16, 2009 at 2:39 pm

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

Michael Williams June 16, 2009 at 3:57 pm

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.

Asif Maknojia August 24, 2009 at 6:39 pm

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 );
        }

Michael Williams August 25, 2009 at 12:09 pm

@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 scene parameter is now ignored.

ScarLight April 13, 2010 at 3:31 pm

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 ;)

Michael Williams April 13, 2010 at 4:43 pm

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 ;)

UnkleDave May 22, 2010 at 6:12 am

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

UnkleDave May 22, 2010 at 6:17 am

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

myMovieClip = new LoopingMovieClip() 
LoopingMovieClip.NextFrame()     // uses the custom function

superClip = new MovieClip()
superClip.NextFrame() // uses it's own, 'default' function

Is there a way to do the following??

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 Williams May 29, 2010 at 12:31 am

Hey UnkleDave,

Hmm. No, I don’t know of a way to do that. Why would you like to?

fakeartist August 4, 2010 at 11:02 am

Excellent!!! Heaving read too many books on AS3, I finally understood the concepts of extends, override and super from your tutorial. Waiting for more…

Ian August 9, 2010 at 3:33 pm

Thanks for this very clear explanation of something I’ve been wondering about. Well done!

Michael Williams August 21, 2010 at 12:28 am

Hey fakeartist, hey Ian — thanks very much! I’m very happy to hear that :)

jeremias December 18, 2010 at 8:24 am

thanks you so much!

Xadjim December 21, 2010 at 2:08 am

Well explained :) thumbs up

Giri January 4, 2011 at 6:04 pm

Oh thanks a lot Michael! Finally I got it, those three things are the central of OOP and now I know :D
Keep writing

badcoder March 21, 2011 at 3:45 pm

Thx for posting. It helps me.

manoj August 2, 2011 at 7:36 am

Hi James,

dont you think this is a better idea, instead of using above ?

package com.zisi.data
{
import flash.display.MovieClip;

public class SuperMovie extends MovieClip 
{

public function SuperMovie() 
{

}

override public function nextFrame():void 
{
    if (currentFrame == totalFrames) {
        gotoAndStop(1);
    }else {
        nextFrame();
    }
}

}

}

manoj August 2, 2011 at 7:36 am

Hi James,

dont you think this is a better idea, instead of using above ?

package com.zisi.data 
{
    import flash.display.MovieClip;

public class SuperMovie extends MovieClip 
{

public function SuperMovie() 
{

}

override public function nextFrame():void 
{
    if (currentFrame == totalFrames) {
        gotoAndStop(1);
    }else {
        nextFrame();
    }
}

}

}

manoj August 2, 2011 at 9:02 am

sorry, the above code will be -

override public function nextFrame():void 
        {
            if (currentFrame == totalFrames) {
                super.gotoAndStop(1);
            }else {
                super.nextFrame();
            }

    }

Chom August 4, 2011 at 12:10 pm

Your skribit service is not available. Please, check.

Voles August 13, 2011 at 5:08 pm

Thank you, solved my problem!

Giuseppe October 25, 2011 at 1:56 pm

Really useful to clarify my ideas.. congratulations! And of course many thanks… :)

Giuseppe October 25, 2011 at 3:50 pm

But.. I didn’t understand just one thing.. why and when should I use “super()” since when I extend a class the constructor runs by default!
In other words I didn’t understand how to override a constructor! Thanks for all :)

Giuseppe

Michael James Williams October 27, 2011 at 8:18 am

@manoj: Neat idea! Yeah, that works too :) And I guess it is better, since maybe nextFrame() does more than just call gotoAndStop().

@Chom: Unfortunately, Skribit shut down :( I’ll switch to Google Moderator at some point.

@Voles: Glad to hear it!

@Giuseppe: That is a great question. It turns out that, if you don’t include a call to super() in your constructor, then Flash will just run it anyway, before your construcutor code. I’ve added a note about this to the tutorial – thanks for asking!

Giuseppe October 31, 2011 at 1:49 am

Oh thank you, James!!! Now I understood why… :)

Leave a Comment

Writing code? Write <pre> at the start and </pre> at the end to keep it looking neat.

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: