< Day Day Up > |
Private Attribute for MethodsA new feature within ActionScript 2.0 gives us the ability to determine from where methods can be accessed. This is done with the keywords public and private . Methods that will not be used outside the class should be declared as private . In the following example, the methods doDrag and doDrop will be used only within the Drag class and therefore should be referenced as private : class Drag extends MovieClip { function Drag () { onPress = doDrag; onRelease = doDrop; } private function doDrag () :Void { this.startDrag(); } private function doDrop () :Void { this.stopDrag(); } } }
In Flash MX 2004, private methods are not truly private because they are inherited by any subclasses from that class. In the following example, the RollEffect class inherits all methods from the Drag class even though the methods have been assigned the private attribute in the Drag class: class RollEffect extends Drag { function RollEffect () { onPress = doDrag; onRelease = doDrop; onRollOver = doAlpha; } private function doAlpha () :Void { this._alpha = 50; } } In most OOP languages, inheriting from a method, but not being able to access it, is known as working with a protected method. However, in ActionScript 2.0, protected methods are referred to as private. There is no way in ActionScript 2.0 to build a class that does not inherit its private properties. Of course, it is certainly possible in ActionScript 2.0 to access a property directly, as shown in the following code: class Loan { var interestRate function Loan (latestRate :Number){ this.interestRate = latestRate } } There is nothing wrong with this approach, but using methods will result in more maintainable and scaleable applications. Data HidingAs we saw in Chapter 3, it is a best practice to always access properties within a class through methods instead of directly accessing the property. When we use methods to access a property, we have more control over any changes that are made because the property itself is hidden and accessed only through external methods. Data hiding makes code more maintainable and scalable. Let's take the TextField class in Flash MX 2004 as an example of data hiding. Throughout many applications, people have repeatedly accessed the .text property directly, as shown in Figure 4.4. Figure 4.4. Setting the .text property directly.
Setting a property directly could result in maintainability problems if Macromedia ever decided to change the name of the .text property to another name. We would have to go through every single line of code of every application built and change the property references to the new property name. However, if the text field had been built with getter/setter methods (discussed in the next section), all we would have to do is change the property name within the method and it would not affect the end application at all.
Getters and SettersTo completely understand the importance of getter/setter methods, we are going to create a movie clip with a text field inside it. Instead of accessing the .text property directly, we are going to access the property through two new methods, getText() and setText() . The first step is to define a new class that extends the current text field class, as shown in the following code: class TextControl extends TextField { function TextControl () {}; //Constructor }
In Chapter 3, we looked at two ways of creating getter/setter methods. We determined that the best practice was not to use the keywords get and set . Because we extended the textField class, the .text property is inherited by our new TextControl class. All we need to do is build getter/setter methods for that class. For instance, in the setText method, we set the autoSize property of the textField to true , and we populate the text property to the value that is passed in from the method. The getText method returns the value of whatever is in the current textField . The advantage of this approach is that it separates the development of the class from the use of the class. No matter what happens, the TextControl class will use getText() and setText() even if other parts of the code change. As an example of the functionality, assume that our client would now like all textFields to be one font. We could set that up in setText(): class TextControl extends TextField { function TextControl () {}; public function setText(textToSet :String) :Void { trace (this.theText); this.theText.autoSize = true; this.theText.text = textToSet; } public function getText () :String { return this.theText.text; } } The final step in building a new TextControl class is to link a visual object, which, in this case, is a text field inside a movie clip, to the class we just built. You can do this with the following step sequence.
Building Implicit Getters/SettersImplicit getter/setter methods are one way to access properties in ActionScript 2.0. Implicit methods use the keywords get and set . The big difference between explicit and implicit getter/setter methods is how they are called. They are referenced by the end user as properties even though behind the scenes they are actually methods. For example, in v1 components , setDataProvider() was a method. In v2 components, it is now an implicit setter property (still really a method) and accessed as shown in the following code: var myArray :Array = new Array(); myArray[0] ="US"; myArray[1] = "Canada"; var myCombo.dataProvider = myArray; These getter/setter methods cannot share the same name as the underlying property. The following code would be a bad practice because text is an existing property of the TextField class: class TextControl extends TextField { function OOText () {}; public function set text(textToSet :String) :Void { trace (this.theText); this.theText.autoSize = true; this.theText.text = textToSet; } public function get text () :String { return this.theText.text; } } If we wanted to use implicit getter/setters, we would need to change the name of the methods to something else, such as _text , as shown in the following code: class TextControl extends TextField { function TextControl () {}; public function set _text(textToSet :String) :Void { trace (this.theText); this.theText.autoSize = true; this.theText.text = textToSet; } public function get _text () :String { return this.theText.text; } } The getter/setter methods would be invoked by simply referencing the _text method just like a property, as shown in the following code: <instance>._text = "OOPActionScript"; <variable> = <instance>._text; With implicit getters/setters, it is impossible for the end user to tell if a method or a property is being accessed and this is why we encourage the use of explicit getters/setters. Of course, by using implicit getter/setters, we still only have to make changes in the class, and not in the use of the class, so those advantages are retained. |
< Day Day Up > |