Warning: Declaration of thesis_comment::start_lvl(&$output, $depth, $args) should be compatible with Walker::start_lvl(&$output, $depth = 0, $args = Array) in /nfs/c03/h01/mnt/50298/domains/gamedev.michaeljameswilliams.com/html/wp-content/themes/thesis_18/lib/classes/comments.php on line 0

Warning: Declaration of thesis_comment::end_lvl(&$output, $depth, $args) should be compatible with Walker::end_lvl(&$output, $depth = 0, $args = Array) in /nfs/c03/h01/mnt/50298/domains/gamedev.michaeljameswilliams.com/html/wp-content/themes/thesis_18/lib/classes/comments.php on line 0

Warning: Declaration of thesis_comment::start_el(&$output, $comment, $depth, $args) should be compatible with Walker::start_el(&$output, $object, $depth = 0, $args = Array, $current_object_id = 0) in /nfs/c03/h01/mnt/50298/domains/gamedev.michaeljameswilliams.com/html/wp-content/themes/thesis_18/lib/classes/comments.php on line 0

Warning: Declaration of thesis_comment::end_el(&$output, $comment, $depth, $args) should be compatible with Walker::end_el(&$output, $object, $depth = 0, $args = Array) in /nfs/c03/h01/mnt/50298/domains/gamedev.michaeljameswilliams.com/html/wp-content/themes/thesis_18/lib/classes/comments.php on line 0
Extends, Override and Super — Michael James Williams

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:

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:

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:

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:

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:

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:

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:

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:

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 😛

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 😛

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 😀

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 😀
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.

Previous post:

Next post: