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.

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

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.

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

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.

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

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.

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

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

MyClass.prototype.moveMe = function(){
        this._x+=5;
}

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.