Most developers who have worked with ActionScript have probably worked with, or at least heard of, the "prototype" method of object inheritance that was prevalent in ActionScript 1. However, most people never properly learn the difference between the it and the class-based system and so are unable to make good use of these powerful programming techniques.

Although many see the prototype method as old and outdated, it actually has many useful applications that can be used right alongside modern class-based inheritance techniques.

To begin with, let's talk about the class and how inheritance works there.

When you create a class, you are creating a number of functions and properties that become available to any other class that will be extending it. Let's start with the following class:

public class myClass {

public function function1() {
trace ("I am function 1");
}//function1

}//myClass class

Here the class myClass has defined a function named function1. All this function does is to send a string to the output window but it can be as complex as you need it to be.

Now, suppose we want another class where we want to copy the functionality of function1 but without re-writing it. This is accomplished via the extends keyword like this:

import myClass;
public class anotherClass extends myClass {
}//anotherClass

Because this new class extends the myClass class, it will now automatically have the function function1. This is very standard and is the very core of object-oriented programming. It's easy to see why this way of programming can save you so much time; instead of constantly copying or re-writing the same code wherever you need it, you simply extend a class where that functionality already resides.

The direction for this class-based inheritance is top-to-down. That is, the top class (myClass) holds its functionality in its class definition and then pushes a reference to this functionality into the anotherClass class that inherits it. This second class can override the original function1 function or it can create a hybrid of the two by overriding and calling the super-class function at some point. When I say override, I don't mean that the original function is changed or removed in any way, what this means is that the override function sits on top of the original function.

What's important to understand here is that the original myClass class remains unaffected. In other words, changing anotherClass, even changing its own version of function1 won't affect myClass.

This is a very useful and important feature because extending classes can always rely on a stable chain of command. If they need custom functionality they can override the function but no other classes will be affected.

In the prototype model, however, this is not the case. Here what we can do is affect the original myClass function so that any classes that extend it will also automatically be extended.

Here's an example:

//Define the original class
public class myClass {

public function function1() {
trace ("I am the original function1!");
}//function1

}//myClass

//Create a class that updates the prototype!
import myClass;
public class updateClass {

public function updateClass() {
myClass.prototype.function1=function() {
trace ("I am a new function1. The old one is gone!");
}//prototype
}//constructor
}//updateClass

//Now we extend the previous class as before
import myClass;
public class extendingClass extends myClass {

public function extendingClass() {
this.function1();
}//constructor
}//extendingClass

Now the order of operation is critical. If the extendingClass class were to be created first, the trace window would show "I am the original function1!". However, if updateClass were created first, the function1 function would effectively be replaced with its own version so that any new extending class would now use the new one. The trace window would show "I am a new function1. The old one is gone!"

In other words, by affecting the prototype of the myClass class, we are updating the very top class itself and any classes that extend it are automatically updated as well.

The direction of inheritance is now down-to-top-to-down.

The danger in using prototyping like this is that you can very easily overwrite a critical function that another extending class may be depending on. For example, our myClass function1 function performs a very specific routine. Using class inheritance this routine is *always* the same and can be counted on. Using prototyping, however, the new functionality is introduced at runtime and, if the program is complex, it's possible for this to happen at any time and from any location. Suddenly function1 starts doing something completely different and unexpected.

Clearly this type of behaviour can be very problematic, but it can also be useful. As a careful developer you can update an object's prototypes so that the behaviour is the same (the old functions are called) but you also introduce your own functionality to make them more powerful.

For example, you may want to know whenever a MovieClip is told to gotoAndPlay. You could either go to any class that perform this action and update the code there, or you can update the prototype to trace out this action and call the original gotoAndPlay function. All the MovieClip instances still perform the same action but now you've very effectively added an extra bit of information with a single line of code instead of many.

Prototype updates can be great time-saving devices but because of their broad scope, they should be used with extreme caution. Before changing any prototype you should first ensure that you fully understand what it is you are possibly replacing so that you can properly emulate it with your own code.