AS1 OOP: Inheritance
by senocular
Deconstructors
A deconstructor is a type of method for object instances
that is used to essentially delete that object as best as it
can. Just as a constructor “constructs” an object, a
deconstructor would “deconstruct” it. In other programming
languages, deconstructors are used to deallocate or free the
memory used by dynamically created content in objects. With
Flash, though, objects exist as long as their exists a
variable reference to that object. Deleting an object is
just a matter of deleting or re-defining all references to
that object. When all references are gone, Flash take care
of deallocating all memory associated with that object on
its own. So, when it comes down to it, there really isn’t
much in the way of deconstructor functionality for objects
in Flash and Flash has no way of handling them by default.
This doesn’t mean they can’t be made. There are certain
situations where you might need a deconstructor of sorts to
help with the cleanup of a no longer needed object.
One such instance is with the use of ASBroadcaster. When
a new instance is created and added as a listener of the
class constructor, a reference to that object instance is
kept in the constructor’s listeners list. If you ever decide
to delete an object, you would too want to remove that
object from that list with removeListener. This way, while
cycling through the listeners, calling event methods, the
constructor wouldn’t be going through supposedly deleted
objects. Of course, if they’re still in the listeners list,
a reference still exists and the object wouldn’t be
technically deleted even though the variable it was assigned
to during creation was.
Deconstructors can also be used for other needs required
in object removal such as reducing a static count property,
keeping track of the number of instances created etc. Let’s
apply a deconstructor to the child example. After all,
children are frequently deleted, right.
- // movieclip to send onEnterFrame events
- this.createEmptyMovieClip("onEnterFrameEvent",1000);
- ASBroadcaster.initialize(onEnterFrameEvent);
- onEnterFrameEvent.onEnterFrame = function(){
- this.broadcastMessage("onEnterFrame");
- };
- // child class constructor
- Child = function(name){
- Child.count++; // count children
- this.name = name;
- this.ageInSeconds = 0;
- Child.addListener(this);
- };
- // child class deconstructor
- Child.prototype.deconstruct = function(){
- Child.removeListener(this); // remove as listener
- Child.count--; // adjust count
- // anything else you might need to "clean up"
- };
- Child.prototype.grow = function(){
- this.ageInSeconds += 1/20;
- trace(this.name + "'s age: "+ this.ageInSeconds);
- };
- onEnterFrameEvent.addListener(Child);
- ASBroadcaster.initialize(Child);
- Child.onEnterFrame = function(){
- this.broadcastMessage("grow");
- };
- // new instances
- son = new Child("Sam");
- daughter = new Child("Jessica");
- // delete son; // <- ineffective
- // though deleted, son will still grow since
- // its still referenced in the listeners list
- // of the child constructor. It will need
- // to be removed as well.
- // call son deconstructor
- son.deconstruct();
- delete son; // removes son variable reference
- /* Example output:
- Jessica's age: 0.05
- Jessica's age: 0.1
- Jessica's age: 0.15
- Jessica's age: 0.2
- Jessica's age: 0.25
- */
- /* Example output if only used delete son:
- Sam's age: 0.05
- Jessica's age: 0.05
- Sam's age: 0.1
- Jessica's age: 0.1
- Sam's age: 0.15
- */
A deconstructor like this isn’t a solve-all solution
though. It takes care of business for the class itself. You
may still have other object references out there pointing to
the object you might want to delete. Its up to you to take
care of that best you can by keeping organized in your
variable handling.