ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
OOP and inheritance in Flash
http://www.actionscript.org/resources/articles/72/1/OOP-and-inheritance-in-Flash/Page1.html
Gabriel Gittings
This user is yet to take control of their account and provide a biography. If you are the author of this article, please contact us via support AT actionscript DOT org. 
By Gabriel Gittings
Published on September 9, 2005
 
Tutorial details:
Written by: Gabriel Gittings [email:[email protected]]
Time: 45 minutes
Difficulty Level: Intermediate
Requirements: Flash 5 and higher
Topics Covered: Learn about inheritance in Flash's OOP structure.
Assumed knowledge: Variables, Paths, Functions, Objects, Methods, basic OOP.
Download FLA

Page 1 of 2
Tutorial details:
Written by: Gabriel Gittings [email:[email protected]]
Time: 45 minutes
Difficulty Level: Intermediate
Requirements: Flash 5 and higher
Topics Covered: Learn about inheritance in Flash's OOP structure.
Assumed knowledge: Variables, Paths, Functions, Objects, Methods, basic OOP.
Download FLA

Intro

The most difficult thing to grasp in Flash for the non-programmer is Object-Oriented Programming techniques. Luckily for us in the latest release of Flash, Flash MX. Object Oriented programming techniques have become easier than ever to start using. There are many reasons that OOP is helpful in flash, from the designer to the application developer we can all benefit from this technique of programming. The Main advantages to using OOP techniques in flash can be summarized with two terms - encapsulation and centralization. Encapsulation gets to the heart of why OOP in all programming languages is beneficial. By "encapsulating" your code into a code structure that can be reused and be unaffected by changes in the rest of your program you are saving your self time in the current project because you aren't breaking already working code with changes and you don't have to rewrite code that you use frequently. Encapsulation also helps to organize your code so it is easier for others to understand ( which doesn't mean your code shouldn't be well documented! ). Centralization is really a term that really only relates to flash. The biggest difficulty that programmers have when they start using flash is that the code can easily be scattered every where, nested deep with in movie clip after movie clip, which can make it very difficult to track down bugs. This tutorial is aimed at introducing everyone to OOP in Flash MX and hopefully being able to use it right away. Some of the concepts can be used in Flash 5 though it requires a little bit more in depth knowledge of flash 5 actionscript and OOP to accomplish the same tasks. You will soon realize once you start down this path of using and learning OOP that the more you learn the more you realize you don't know about the subject. But don't get discouraged it takes time, patience, and good ole' fashion trial and error.

O-O Basics

First things first. What makes OOP Object Oriented? Luckily for most Flash users this concept is already in front of us and being used even if we don't know we are using Object Oriented principles. When we define a Movie Clip in the Symbol Library and drag it to our stage we are creating an object. This process in O-O terms is known as instanciation. I will cover this term a little more shortly. This tutorial is meant as a starter for your OOP endeavors. There is a great tutorial that you should read either before or after this one that will either scramble your brain or make it all come clear. Robin Debrieul has written an incredible tutorial on the subject that you can find at his site http://www.debreuil.com/docs/ch01_Intro.htm. We will begin this discussion from the top down. So, lets talk about classes.

Classes

Actionscript is based on an ECMA standard for scripting languages. This is the same standard that JavaScript is based on so if you have and understanding or seek more info on O-O in an ECMA language pick up a good JavaScript book. I recommend the definitive guide for JavaScript from O'Reilly. So, what does this have to do with classes? Well since ActionScript is a ECMA language it actually doesn't technically have classes (huh?). For those of you who have been learning or spending time in the forums talking about OOP this may come as a shock to you, it did to me. ActionScript and JavaScript are what are known as prototype based languages. This means that you have a constructor and the prototype object for the constructor, these two objects basically make up your "Class" (which is how I will refer to them for the rest of the tutorial). The prototype object is where flash looks for all you methods and variables. ( For example ever used .getBytesLoaded? This method is defined in the prototype of the MovieClip "class")

The constructor is like a template for the objects that you want to create for your program. Think of it as your blue print for how to create an object (not how you will use it, that comes later in the prototype section). A brief example..

[as]MyCircleClass = function(){
        this.color = red;
        this.size = big;
        this.name = "myCircle";
}
[/as]

Now I always have hated these abstract examples that don't directly relate to flash so for those like me here is an example. ( don't use this in flash without reading the whole tutorial yet cause it won't do anything)

[as]CircleClass = function (){
        this._x = 200;
        this._y = 400;
        this.alpha = 60;
}
[/as]

Sounds easy enough right? But how and when does flash know when to set these variables and what does "this" refer to. Since this is a template you have to build your object from it or rather you have to instanciate the constructor ("class"). This is accomplished in several ways depending on whether you are subclassing a MovieClip class or creating an internal object for handleing data. I will start with the non-subclassed type because it shows how O-O is supposed to work. ( Subclassing MovieClips can be tricky business and it is usually what people want to use first in the O-O endeavors Flash MX makes it much easier with the new Object.registerClass() method which I will cover later). Before the example the keyword this when used in a constructor or a prototype refers to the instance that is created from the class. Lets look at an example.

[as]MyCustomClass = function(){
        this.name = "customclass";
        this.description = "this is my first class";
}
customClassInstance = new MyCustomClass();
[/as]

Whala! That sure was easy right? By using the global method "new" you are instanciating your constructor ("class") and creating an object with the identifier of customClassInstance. And encase you are wondering the keyword "this" that precedes all the properties refers to your instance in scope. So once you instanciate your class, "this" refers to customClassInstance. Easy enough, I will cover the use of Object registerClass() after a brief explanation of prototypes.

Prototypes

So, what is this thing you keep hearing about called a prototype? And how do you use it. Well a prototype is an object that is part of all classes in flash that holds all of the methods for that class. What does this mean you ask? Well think of the prototype as a holding place for all the methods and properties for the class and the objects that are created from the class. Instead of copying the methods to each instance of the class and creating a lot of memory over head flash keeps all the methods (assuming that is where you put them) in the prototype.

Lets say you define a function in the first frame of a movie clip. You are effectively attaching a method to the movie clip object. So when you call this method flash first looks at the object (your movie clip) for that method. When it finds it it goes no further.

[as]onClipEvent(load){
        moveMe = function(){
                this._x+=5;
        }
}

onClipEvent(enterFrame){
        this.moveMe()
}
[/as]

So what is different when you put your method in the prototype. First lets look at some of the built in methods. A good example of this is .getBytesLoaded(). When you call this method for a movie clip you say myMC.getBytesLoaded() and it returns the number of bytes that have loaded in your movie clip. When you call this method flash first looks in the object myMC. When it doesn't find it there it looks at its constructor (which is a property you can access via __proto__ or .constructor) property which tells flash that the class that created this object is the MovieClip class. So, it then looks at it's prototype object, MovieClip.prototype, where it find the method getBytesLoaded(). The great thing about flash (and most languages) is that you can change the prototype properties of the built in classes. Here's an example.

[as]MovieClip.prototype.getBytesBackUp = MovieClip.prototype.getBytesLoaded;

MovieClip.prototype.getBytesLoaded = function(){
        trace("gotcha sucka!!");
}

_root.getBytesLoaded();
[/as]

Cool Huh!! Of course you don't have to ruin all the built in methods with the prototype object you can add to all the classes in flash as well. There was a big fad (and some people still do it) when people started to discover the benefits of putting methods in MovieClip.prototype when Flash 5 was out for about 6 months. This is a handy but poor OOP way to code. It is handy because then those methods are available to all the movie clips in your movie. It is poor OOP in that you pollute all your movie clips with methods that they may not need. So what is the solution? Well in comes inheritance and subclassing.

Continued overleaf...

Page 2 of 2

inheritance

inheritance is probably the hardest concept to understand in OOP for Flash. Luckily it has been made much easier for movie clips by the folks at Macromedia with the advent of Object.registerClass(). inheritance is just like it sounds you have one class, which is referred to as a super class, and then your child class that you want to inherit the methods and properties from the super class, referred to as your subclass. So, inheritance is just the process of telling flash what class you want your custom class to inherit from. You can even inherit from a custom class to a custom class. The tricky part about understanding how to use this concept in your programing is how Flash treats movie clips. Movie clips technically are objects that are instances of the class MovieClip. What makes having your movie clip inherit methods from a custom class tricky is that technically once you movie clip is on stage it is and instance of the MovieClip class and not a class by itself. This means that in flash 5 you had to do some tricky coding to get you movie clips to inherit custom class methods. In Flash MX you just have to use Object.registerClass(). Lets look at a quick example.

[as]MyCustomMCClass = function(){
        this._x = 200;
        this._y = 150;
        this._xscale = 150;
}

MyCustomMCClass.prototype = new MovieClip;
Object.registerClass("square", MyCustomMCClass);
MyCustomMCClass.prototype.onEnterFrame = function(){
        this._x+=5;
}

_root.attachmovie("square","mysquare",1);[/as]

First off if you want this code to work you need a movie clip in your library with the linkage name of "square" otherwise it won't work. And I am sure you are asking yourself what the MyCustomMCClass.prototype = new MovieClip; part is all about. Well you might have had an inkling that it is setting up the inheritance chain for your custom class. And you'd be right! What this line does is say create a prototype object for my class that is an instance of the MovieClip class. By doing this you are telling flash that if a method is called that is not in your custom class prototype look in the MovieClip.prototype to find it. It is imperative that you put this line of code in before your write any of your prototypes because this call erases the prototype of your custom class. The Object.registerClass() method is a built in method that attaches the custom class to your movie clip.A class can be registered to several movie clips but, each movie clip can only have one class registered to it. And if you are wondering about the onEnterFrame bit it is a part of the new event model in Flash MX read the tutorials on events to learn more about it.

The last tool you will need to finish your beginning knowledge of inheritance in Flash is __proto__. The first time I saw this attribute I thought what the hell is this? __proto__ is actually quite slick. __proto__ is a property that "holds" the link to the classes prototype that instanciated the object. Know take a moment and reread that last sentence...... ... OK you with me? Now that you understand that you will see that since __proto__ is a read/write property of an object, you can change the inheritance chain of an object. Lets look at a brief example.

[as]MyCustomMCClass = function(){};
MyCustomMCClass.prototype = new MovieClip;

MyCustomMCClass.prototype.Init(){
        this._x = 200;
        this._y = 150;
        this._xscale = 150;
};

MyCustomMCClass.prototype.onEnterFrame = function(){
        this._x+=5;
}
_root.attachmovie("square","mysquare",1);

_root.square.__proto__ = MyCustomMCClass.prototype;
_root.square.Init();
[/as]

The best part about __proto__ is that you can hot-wire up movie clips that are already on the stage or movie clips that you created dynamically with createEmptyMovieClip(). Very cool! The one thing I am sure you noticed is that I moved the code from the constructor to a method called Init() that I call after the hot-wire. Well since you never technically instanciate the class you never call the constructor. So, you need to create an initialization method that you call to call the constructor. This method only has to be in the last class of the inheritance chain and should include a call to super() (super is explained below ) if the are other constructors up the chain you want to call. So in your movie clip gets instanciated from the MovieClip class. You then overwrite that property by assigning it to your custom class which inherits from the MovieClip class. Another way that the __proto__ property has been used is to setup and inheritance chain. So instead of the myClass.prototype = new SuperClass() you can write myClass.prototype.__proto__ = SuperClass.prototype. What's the difference? Well when you use the __proto__ way of inheritance you don't unnecessarily call the constructor. Unfortunately the super() method doesn't work with this technique of setting inheritance so you would need to call an Initialization function for each class in the inheritance chain. Don't let this last part confuse you though. For now just stick with the first method of inheritance. Now one little caveat to the __proto__ property is that Macromedia never intended it to be used this way. They had designed it as a read only property. So, what does this mean to you and I? Well since it is not supported by MM you may find your code breaking in later versions of the Flash Player should MM decide they want to really make it a read only property. So, be careful with your usage of __proto__ and don't use it on any sites that may be up for a long time. The example .FLA has some sample code for using __proto__ commented out. Just read the comments to see how to use it with the example.

Putting it all together

So what if you have several methods that you want to share with several movie clips but those movie clips also need there own methods. Well you would subclass your custom MovieClip subclass. This is a more complex example so hold on tight.

[as]SuperClass = function(){
        this._xscale = this.xscale;
        this._yscale = this.yscale;
};

SuperClass.prototype = new MovieClip;
SuperClass.prototype.onMouseDown = function(){
        this.mouseDetected();
} ;
SuperClass.prototype.mouseDetected = function(){
        trace(this._name + " mouse down event has been triggered");
};

SubClass = function(){
        this._x = this.x;
        this._y = this.y;
        super();
};

SubClass.prototype = new SuperClass;
Object.registerClass("square", SubClass);

SubClass.prototype.onEnterFrame = function(){
        this.followMouse("_x", this.speed);
        this.followMouse("_y", this.speed);
};

SubClass.prototype.followMouse = function(property, rate){
        this[property]+=(_root[property+"mouse"]-this[property])/rate;
};

SubSubClass = function(){
        super();
};

SubSubClass.prototype = new SubClass;
Object.registerClass("circle",SubSubClass);

SubSubClass.prototype.onMouseDown = function(){
        trace(this._name+" has overridden the super class mouse down method");
};

_root.attachmovie("square", "mysquare1",1,{xscale:150, yscale:150, x:200, y:200, speed:30});

_root.attachmovie("square", "mysquare2",2,{xscale:50, yscale:50, x:100, y:100, speed:10});

_root.attachmovie("circle", "mycircle",3,{xscale:80, yscale:80, x:500, y:500, speed:20});
[/as]

Whoa Nelly! There is a lot of crazy stuff going on there! Well, I have included a working fla with this code so you can test it for yourself. I packed a lot of new code and concepts into this little example. Have patience I will explain all of it. The first thing you will notice is that I didn't include the Object.registerClass() for the Super Class. This is because we want our movie clips to inherit the methods and properties of our sub class as well. After the inheritance chain for the super class is set up to inherit from the MovieClip class you will notice I created a function that I call in the event handler onMouseDown. The reason for this is that it follows along with the term encapsulation that I described at the start of the tutorial. You want to abstract your code as much as possible so that if you want to change parts of it later you don't have to rewrite any code. Since I enclosed my code in a method if I want to toggle on and of a method or rather I have to methods that roughly represent an ON and OFF state of something in my movie I can call either method depending on the state. Another trick that people use is to set an event handler equal to a method in there object. So, SubClass.prototype.onMouseDown = mouseDetect; The advantage to this is you can have several different methods use the event handler at different times. Lets say that you have a scripted tween that you want to run while the mouse is down but stop when it is up. You would write.

[as]MyClass.prototype.onMouseDown = function(){
        this.onEnterFrame = this.moveMe;
}

MyClass.prototype.onMouseUp = function(){
        this.onEnterFrame = null;
}

MyClass.prototype.moveMe = function(){
        this._x+=5;
}
[/as]

Pretty Slick huh? all right back to the inheritance example. The very next thing that you will probably notice is the method super() that gets called in the constructor of the SubClass. What is this you ask? Well it is another one of those things that macromedia wrote in there to help out with the sub classing of movie clips. Technically the MyClass.prototype = new SuperClass; should call the constructor and setup any properties or variables that are inside of it. Unfortunately to get the constructor to set movie clip properties such as _x or _yscale you have to call super() to call the constructor.

Probably the next piece of code that seems confusing is the method that I call in the onEnterFrame event handler. I wrote this method specifically to show how you can abstract a piece of code so that it is completely encapsulated. This method uses the tried and true zennox's paradox equation for easing. With this method you can move movie clips, grow movie clip, or pretty much change any movie clip property at a rate you specifiy. The most confusing thing about the way this is written is how you pass the property. Since you are passing a property flash has to evaluate it at run time or it will think it is an undefined variable. I've never heard a good explanation as to why this is but basically you are using the array evaluation operator to evaluate a string. This string evaluates to a property when the keyword "this" is in front of it (you could actually use _root. or a specific instance name here as well but we are trying to abstract the method).

The second to last concept I want to get across is that of overridding the prototype object. Remember earlier when I talked about how flash looks up the chain of prototypes to find methods and properties? Well, by assigning a new onMouseDown handler to the subsubclass flash will see this method before the one in the superclass and go no further. This means that you have "overridden" the superclass method. It doesn't mean that it isn't still in the superclass though, take a look at the sample fla. and you will get a better idea.

Almost there! The final concept I want to show you about using OOP in Flash MX is the new .attachmovie() method. For those of you who used this method in Flash 5 you are probably wondering what the curly bracket thing is all about. The curly bracket thing is what is known as an instanciation object. Huh? It is basically a way to pass information to your constructor that is specific to your object. The way that it works is that it is assigning those variables as properties to your object. So, {myVariable:Value} is seen in the instance as this.myVariable = Value. You will notice in the constructors that I access these properties with the keyword "this". Very Nice!

Well that concludes this first step (or second depending on what you have read so far!) in your journey to understanding OOP. Take a look at the sample fla. and play with it, break it, do what ever it takes to start seeing the light at the end of the tunnel!

Good Luck.