Getter and Setter Properties
Often you may find yourself writing methods whose sole
purpose is to alter a particular single property or aspect
of an instance. An existing example of this can be seen in
the MX scrollbar component with setEnabled. You can set the
enabled aspect of the scrollbar by passing in either true or
false to that setEnabled method. There's also a method to
check that value, getEnabled. Now if you think about regular
buttons, they too have an enabled aspect. For regular
buttons, though, enabled is a property handled by direct
assignment and not through methods such as setEnabled and
getEnabled for a scrollbar. If they are doing the same
thing, one would think the scrollbar too could have just a
property instead of using methods, right? Well, the problem
is that a scrollbar is made up of many buttons and elements
that require extra effort to actually "disable" the
scrollbar, therefore it must use a method to handle all the
necessary operations needed to turn the scrollbar from
enabled to disabled. Though it may seem like a minor
infection of enabled standards, there is a cure. That cure
lies in addProperty.
The addProperty method is a function allowing you to
create a property in an object (which could be a prototype
object) that uses two functions, a get and set, to handle
its definition. The get function is used when the property
is checked and the set function when it's assigned a value.
This allows the conversion of two functions into one
property.
scrollbar.setEnabled(true);
trace(scrollbar.getEnabled()); // traces true
to
scrollbar.enabled = true;
trace(scrollbar.enabled); // traces true
Get and set methods are accessor methods. They provide a
method interface to a property or aspect of an object. Using
addProperty, you have the ability to make a property that
behaves based on defined accessor methods. This allows your
basic property to behave in a very strict manner. For
instance, you could set up a property that, though it may
have been assigned one value, returns another – all based on
the definition of the get and set functions. A more
practical use would be to assure that the values assigned to
the "property" are valid ones. As an example, lets say we
wanted a selected track for a certain album object. This
album object would only have a certain number of songs, so
we need to make sure a requested track is valid within that
listing.
Album = function(title, artist, tracksArray){
this.title = title;
this.artist = artist;
this.tracksArray = tracksArray;
this.$selected = 1; // used to hold the "real"
selected track number
nowPlaying = new Album("OOP - Yeah You Know Me", "The
Flashers", ["A", "B", "C"]);
nowPlaying.selected = 2;
trace(nowPlaying.selected); // traces 2
nowPlaying.selected = 20;
trace(nowPlaying.selected); // traces 3
You can see here that the added getter/setter property
was added to the prototype of the Album class. That will
still work fine for any instance of Album – just as it were
any other method or property defined there. It will be
accessible to all instances just the same. Notice too that
the getSelected and setSelected are not methods defined in
the Album prototype. This is because addProperty does not
use current methods of an object, but rather, as its name
suggests, adds them – actually copying them. So whatever
methods are used in the addProperty call will be added to
the object though only accessible through the use of that
property. If you want, you can delete the original functions
if you don't want them lingering around. You could use also
prototype methods if you wanted to, though they will be
added into the object a second time – once as they exists as
prototypes, and again for use in the new property. This of
course may be desired if you want both method and property
access to the aspect. In defining those, just be sure to
reference the function fully.
Also, if you noticed, in the Album example there was a
need to keep a "real" hidden property to represent the
actual selected property. The selected property as it was
defined by addProperty was just a method for changing the
real thing. Here, a $ was used to separate the getter/setter
property from the real one. The difference in variable names
didn't have to be a $. It could have been another variable
all together – just something to keep hold the desired end
value. The use of $ serves as an easily seen indicator that
the property is considered "hidden" as you don't often see
variables using the dollar sign in Flash. Feel free to use
what you are most comfortable with when dealing with these
kinds of situations.
For one more example, we can make something similar to
that of the enabled scrollbar. This, instead, will be a
.collapsed property for a simple menu. When not collapsed,
the menu is its normal size and visible. When collapsed,
it's compacted into just an icon.
Example:
[ hidden property set to true when mouse is down ]
// the menucontrol class controls a menu movieclip