Using Composition and Inheritance Together






Using Composition and Inheritance Together

Inheritance and composition aren't in opposition; they can work together. In this next task, you'll build a more generic superclass, MovieClipContainer, which wraps much of the MovieClip class API. Then, you'll rewrite Rectangle to extend MovieClipContainer. Additionally, you'll write a DraggableRectangle class that subclasses Rectangle.

1.
Open a new ActionScript document and save it as MovieClipContainer.as in the same directory as Rectangle.as. Then add the following class declaration:

   class MovieClipContainer {
   }

You'll abstract some of the basic functionality from Rectangle and move it to MovieClipContainer. As with Rectangle, note that MovieClipContainer does not subclass MovieClip.

2.
Define a private MovieClip property called _target.

   private var _target:MovieClip;

The MovieClip property is the movie clip that the MovieClipContainer wraps.

3.
Define the constructor so that it constructs a new empty movie clip.

   public function MovieClipContainer(parent:MovieClip) {
     var depth:Number = parent.getNextHighestDepth();
     _target = parent.createEmptyMovieClip("clip" + depth, depth);
   }

The MovieClipContainer constructor consists of some of the code that was defined in Rectangle. Specifically, when you construct a MovieClipContainer instance, it adds a new empty movie clip to the specified parent.

4.
Define getters and setters for some of the basic properties normally defined by the MovieClip class. For each, simply proxy the requests to the corresponding property of the _target property.

   public function get _x():Number {
     return _target._x;
   }
   public function set _x(x:Number):Void {
     _target._x = x;
   }
   public function get _y():Number {
     return _target._y;
   }
   public function set _y(y:Number):Void {
     _target._y = y;
   }
   public function get _alpha():Number {
     return _target._alpha;
   }
   public function set _alpha(alpha:Number):Void {
     _target._alpha = alpha;
   }
     public function get _rotation():Number {
     return _target._rotation;
   }
   public function set _rotation(rotation:Number):Void {
     _target._rotation = rotation;
   }
   public function get _width():Number {
     return _target._width;
   }
   public function set width(width:Number):Void {
     _target._width = width;
   }
   public function get _height():Number {
     return _target._height;
   }
   public function set _height(height:Number):Void {
     _target._height = height;
   }

Each of the getters and setters corresponds to basic properties from the MovieClip class. When you call a getter or setter for an instance of the MovieClipContainer class, it proxies the request to the corresponding property for the target movie clip. For example, when you set _x for a MovieClipContainer, it proxies that to the _x property of the target movie clip.

5.
Edit Rectangle.as, make it subclass MovieClipContainer, delete the _target property declaration, and replace the first two lines of code in the constructor with a call to the superclass constructor. The new Rectangle class looks like the following:

   class Rectangle extends MovieClipContainer {
     public function Rectangle(parent:MovieClip, width:Number, height:Number, ¬
       color:Number) {
       super(parent);
       _target.lineStyle(0, 0, 0);
       _target.beginFill(color, 100);
       _target.lineTo(width, 0);
       _target.lineTo(width, height);
       _target.lineTo(0, height);
       _target.lineTo(0, 0);
       _target.endFill();
     }
    }

Now that Rectangle subclasses MovieClipContainer, it no longer needs to have a _target property or add the new empty movie clip because the superclass takes care of those things.

6.
Open a new ActionScript file, and save it as DraggableRectangle.as in the same directory as Rectangle.as and MovieClipContainer.as. Add the following class declaration:

   class DraggableRectangle extends Rectangle {
   }

DraggableRectangle subclasses Rectangle so it inherits from both Rectangle and MovieClipContainer.

7.
Add the following import statement to the top of the class:

   import mx.utils.Delegate;

To correct scope issues you'll want to use Delegate.

8.
Define the constructor.

   public function DraggableRectangle(parent:MovieClip, width:Number, ¬
     height:Number, color:Number) {
     super(parent, width, height, color);
   }

DraggableRectangle needs to call the superclass constructor to create the empty movie clip and draw the rectangle.

9.
Within the constructor, define the onPress(), onRelease(), and onReleaseOutside() event handler methods for _target so that they call methods of the DraggableRectangle class.

   public function DraggableRectangle(parent:MovieClip, width:Number, ¬
     height:Number, color:Number) {
     super(parent, width, height, color);
     _target.onPress = Delegate.create(this, onPress);
     _target.onRelease = Delegate.create(this, onRelease);
     _target.onReleaseOutside = _target.onRelease;
   }

When the user clicks on the target movie clip, call the onPress() method of DraggableRectangle. When the user releases the mouse, call the onRelease() method of DraggableRectangle.

10.
Define onPress() and onRelease() methods so they call startDrag() and stopDrag() for _target.

   private function onPress():Void {
     _target.startDrag();
   }
   private function onRelease():Void {
     _target.stopDrag();
   }

When the user clicks on the target movie clip, make it draggable.

11.
Open rectangle1.fla and add the following code after the existing line of code:

   var block:DraggableRectangle;
   for(var i:Number = 0; i < 10; i++) {
     block = new DraggableRectangle(this, 25, 25, 0xFFFF00);
     block._x = Math.random() * 550;
     block._y = Math.random() * 400;
   }

Draw 10 draggable rectangles and place them at random coordinates on the stage.

12.
Test the movie.

When you test the movie, you'll see 10 yellow rectangles placed in random locations. You can click and drag any of the yellow rectangles.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows