As I have made the move from AS2 to AS3, I have run into several situations where Flash refused to let me extend an AS3 class. I have spent many hours pounding my head on the desk, screaming “Why doesn’t this work?!” Well, that may be an exaggeration, but I have definitely spent many hours on this issue.
The problem is related to using direct references to MovieClip instance names in an AS3 class. If you associate an AS3 class with a MovieClip using the linkage property of the MovieClip …AND… you have direct references to any of the MovieClip’s children instance names, you can NOT extend the class. I have created a packet of examples (click here to download the packet) to help demonstrate what I’m talking about:
Example 1 (marked basic_linkage_example in the packet): This is simply an example of the base scenario. The buttons on the stage are each instances of the MovieClip bounceButton, which has a base class linkage of BounceButtonTweenLite. This class handles the rollover functionality of the button (with the help of the amazing TweenLite library) and also provides some other basic functionality, like the ability to enable and disable a button. If you open up this class file, notice that only the child Movieclip with the instance name graphic_mc actually bounces. There is another child MovieClip that provides a hit area larger than the graphic to prevent any rollover “flickering” when the button bounces. This is a great example of needing to target a child MovieClip and doing it directly with the child clip’s instance name.
Example 2 (marked linkage_extension_example in the packet): This shows what happens when I try to extend the BounceButtonTweenLite class with a class called NavButton. notice that the NavButton class does not override any of the base class functionality – it simply adds an init() function and establishes a MouseEvent.CLICK listener. If you try to publish this file, you will see that it throws a couple of compiler errors and it doesn’t work. Again, this is because the BounceButtonTweenLite class contains a direct reference to graphic_mc, which is the instance name of one of its child MovieClips. I can’t extand this class as long as I am using the linkage property to associate the NavButton class with my bounceButton MovieClip.
Example 3 (marked composition_example in the packet): This shows how you can make it work by using a composition method of associating classes with MovieClips. When using composition, the linkage property of the MovieClip isn’t used. Instead, you send references to the MovieClip (and any needed children) into the class. Since the references are no longer tied to timeline instance names, you can extend it without any problems. In this example, I instantiated new instances of the NavButton class and sent references to each MovieClip and it’s child graphic. The code that handles this composition method of associating the MovieClips and their classes is on the main timeline. If this were a real project, I would place the code in another class, but I wanted to keep this simple.
Variations on this same issue keep popping up in my projects. I recently had a project which had several different bounceButton-style MovieClips that each contained different graphics. They all shared the same BounceButtonTweenLite base class. That was no problem. The problem came when I wrapped each of those in another set of MovieClips, each with a base class called SelectorButton. The SelectorButton class had a reference to the inner button’s instance name. It didn’t work. Why? Well, I had 8 DIFFERENT inner button MovieClips that shared a base class. So when the wrapper class tried to reference it, the flash compiler freaked out. It was basically saying: “Hey! You told me that these MovieClips were all the same, but they aren’t!” Even though they had the same basic structure, the MovieClips weren’t EXACTLY the same, so the compiler didn’t like it. Again, a composition method fixed the problem.
Using a MovieClip’s linkage is a great way to associate classes with MovieClips – it’s fast and easy. Frankly, I do it all the time and I’m not likely to quit anytime soon. Unfortunately, as you get better at class-based programming, you will find that the linkage property creates problems like these and that a composition-based structure is a lot cleaner. From an object-oriented programming perspective, composition also helps to separate actionscript code from graphics, making the entire project a whole lot more modular. Big Spaceship uses composition so that their projects can be passed from Flash to Flex and vice versa. They talk about it here (in fact, this post is where I got the idea to use composition to fix my problems with class extension).
I hope that this explanation makes some sense and saves you a little time. As usual, you can download the sample files here.
T-Unit
Yes, indeed.