6.5 Constructor Functions in Subclasses

 <  Day Day Up  >  

Now that we've studied the behavior of properties in relation to inheritance, let's turn our attention to constructors, which we first discussed in Chapter 4.

A constructor function initializes the instances of a class by:

  • Calling methods that perform setup tasks

  • Setting properties on the object being created

When a class is extended, the subclass can define a constructor function of its own. A subclass constructor is expected to:

  • Perform setup tasks related to the subclass

  • Set properties defined by the subclass

  • Invoke the superclass constructor (sometimes called the superconstructor )

In all inheritance relationships, setup and property initialization relating to the superclass occur in the superclass constructor, not in the subclass constructor.

A subclass constructor function, if specified, is formally required to invoke its superclass constructor, via the keyword super , as the first statement in the function. If no such invocation is provided, the compiler adds a no-argument superclass constructor call automatically.


For example, here is a simple subclass function definition:

 class A {   public function A ( ) {   } } class B extends A {   // Subclass constructor   public function B ( ) {     // Invoke superclass's constructor function explicitly     super( );   } } 

The following two constructor function definitions are functionally synonymous. In the first case, we provide a call to super( ) explicitly; in the second case, the compiler provides the call to super( ) implicitly:

 public function B ( ) {   // Invoke superclass's constructor function explicitly.   super( ); } public function B ( ) {   // No constructor call. The compiler provides one implicitly. } 

In general, it's good form to always provide a call to super( ) in a subclass constructor, even if that call has no arguments. If you intentionally omit the call to super( ) , be sure to add a comment explaining why; otherwise , it may look as if you simply forgot it.

If a subclass does not define a constructor function at all, the compiler automatically creates one and adds a call to super( ) as its only statement. Hence, the following two definitions of the class B are functionally identical; the first is an explicit version of what the compiler creates automatically in the second:

 // Explicitly provide constructor class B extends A {   // Declare a constructor explicitly   public function B ( ) {     // Invoke superclass's constructor function explicitly     super( );   } } // Let compiler create default constructor automatically class B extends A { } 

Invoking super( ) anywhere but as the first statement of a subclass constructor function causes the following error:

 The superconstructor must be called first in the constructor body. 

Furthermore, super( ) must not be used twice in a constructor function. (Using super( ) twice also yields the preceding error message because the second use is not the constructor's first statement.)

Restricting super( ) to the first line of a constructor function has the following benefits:

  • Prevents methods from being called on an object that has not yet been initialized .

  • Prevents property access on an object that has not yet been initialized.

  • Prevents property assignments in the superclass constructor from overwriting property assignments in the subclass constructor.

  • Guarantees that constructors in a class hierarchy execute from the top down. For example, if class C extends B which extends A , then when a new C instance is created, A 's constructor runs first, then B 's, then C 's.

Don't confuse the two forms of the super operator. The first form, super( ) , invokes a superclass's constructor function. The second form, super.methodName( ) , invokes a superclass's method. The first form is allowed only as the first statement of a constructor function. The second form is allowed anywhere in a constructor function or instance method and can be used multiple times.


A subclass constructor function can (and often does) define different parameters than its superclass counterpart . This technique allows a subclass to alter the way its superclass instantiates objects. For example, suppose a Rectangle class defines a constructor with width and height parameters. A Square subclass could provide its own constructor that defines a single side parameter (squares have the same width and height, so specifying both is redundant). Example 6-3 shows the code.

Example 6-3. The Rectangle and Square constructors
 class Rectangle {   private var w:Number = 0;   private var h:Number = 0;   //   Rectangle   constructor   public function Rectangle (width:Number, height:Number) {     setSize(width, height);   }   public function setSize (newW:Number, newH:Number):Void {     w = newW;     h = newH;   }   public function getArea ( ):Number {     return w * h;   } } class Square extends Rectangle {   //   Square   constructor   public function Square (side:Number) {     // Pass the side parameter onto the   Rectangle   constructor.     super(side, side);   }   // Earlier in this chapter, we implemented the   Square.setSize( )   method    // with two parameters (   newH   and   newW   ). This time we'll streamline    // the method, allowing only a single parameter to be passed.   public function setSize (side:Number):Void {     super.setSize(side, side);   } } 

When defining a subclass's constructor function, be careful not to unintentionally disable the behavior of a superclass's constructor. In the following example, the ColoredBall class erroneously defines a constructor function that doesn't supply necessary information to its superclass's constructor function:

 class Ball {   private var r:Number;   public function Ball (radius:Number) {     r = radius;   } } class ColoredBall extends Ball {   private var c:Number;   // Here's the problematic constructor...   public function ColoredBall (color:Number) {     // OOPs! No call to   super( )   , so all   ColoredBalls   // will start with no radius!     c = color;   } } 

Wait a minute. Doesn't the compiler automatically supply the call to super( ) ? Yes, it does; however, the implicit call to super( ) doesn't include the necessary radius parameter.

As written, the ColoredBall constructor does not allow us to create a ColoredBall instance with an initial radius defined. Therefore, the ColoredBall constructor must not call only super( ) , but it must also accept radius as a parameter and pass it on to the superclass constructor. Here's the corrected version of ColoredBall , which preserves the Ball constructor's behavior:

 class ColoredBall extends Ball {   private var c:Number;   // All fixed up...   public function ColoredBall (radius:Number, color:Number) {     super(radius);     c = color;   } } 

Notice that, as a matter of good form, we list the superclass's constructor arguments first (in this case, the radius), then the additional subclass constructor arguments (in this case, the color).

6.5.1 Extraneous Superclass Constructor Invocation in Flash Player 6

Due to the historical architecture of ActionScript 1.0, in Flash Player 6-format .swf files, a class's constructor function executes needlessly once for each of its subclasses. For example, the following code shows two simple classes, A and B . Class A 's constructor reports a message to the Output panel when it runs. Class B does nothing but extend class A .

 class A {   public function A ( ) {     trace("A's constructor was executed.");   } } class B extends A { } 

Class A has one subclass, B ; hence, in a Flash Player 6-format .swf file, class A 's constructor executes once, needlessly, even if no instance of A or B is ever created. For example, if the following code appears in a .fla file, then A 's constructor will run:

 var bInstance:B; 

Extraneous constructor executions can perform unwanted tasks, such as attaching a movie clip or incrementing an instance counter. To prevent unwanted code execution, use a parameter that indicates that the constructor is being called intentionally. For example:

 class A {   public function A (doConstruct:Boolean) {     if (doConstruct) {       // Normal constructor code goes here.     }   } } class B extends A {   public function B ( ) {     // Pass   true   to the constructor to tell it to perform initialization.     super(true);   } } 

This problem does not affect Flash Player 7-format .swf files that use ActionScript 2.0. For much more information, see Chapter 12 of ActionScript for Flash MX: The Definitive Guide (O'Reilly).

 <  Day Day Up  >  


Essential ActionScript 2.0
Essential ActionScript 2.0
ISBN: 0596006527
EAN: 2147483647
Year: 2004
Pages: 177
Authors: Colin Moock

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net