You say it's impossible to overload a method in ActionScript 2? I say you're wrong! Well.. okay, you're not entirely wrong. The compiler will not let you overload a method the same way you would in, say, Java... but if you're sneaky about it you can achieve method overloading with ActionScript 2.
First of all, we need to establish what an overloaded method is so more people can follow along. An overloaded method is a method that has one name but multiple argument lists. An argument list is the number of parameters passed into the function along with each parameter's type. For example, function x(y:Number, s:String) has an argument list with length 2. The first argument is of type Number and the second of type String. This is different from function x(s:String, d:Date) because even though the argument list is still lenth 2, the first parameter is a String and the second is a Date. Why is overloading like this useful? Consider the following scenario...
I have a car object that allows me to paint the parts of it. The variable "car" is an instance of the Car class (defined in Car.as) with a public method available called paintPart. Because paintPart is public, I'm allowed to invoke that method on the instance. The paintPart method will take in a part of the car and output the part with a fresh coat of paint. All of the parts of the car are different.. a door is not a trunk, a trunk is not a hood, a hood is not a fender, etc. Because they are all different, they need to painted differently. A door cannot be painted the same as a hood - more care would be needed around the handle, for instance. However, I don't want to have more than one paint method on my car. To make things simple from the point of view of the car, I want to use the same method for all painting, like this:
car.paintPart(door);car.paintPart(hood);
car.paintPart(trunk);
Rather than this:
car.paintDoor(door);car.paintHood(hood);
car.paintTrunk(trunk);
Notice how the first segment has one function to paint parts, where the last segment has 3 different functions. It's easier to remember that if you want to paint part of a car you call paintPart since remembering one method to invoke is easier than remembering 3.
Even though the paintPart name is the same for all calls to it in segment 1, the method itself needs to do different things because each part passed in is a different type of car part. This is where method overloading comes to the rescue. We can re-use the method name and have it do different things based on its argument list.
In other languages, overloading is done automatically by the compiler. It "knows" which function to call based on the type and number of parameters. We would define paintPart 3 times with different argument lists. One would take in a Door object, one a Hood object, and another a Trunk object. The compiler would know the difference and call the correct function at run time.
In ActionScript 2, even though the language is strongly typed, the compiler will not do method overloading for you. You will get a syntax error if you try to define a function more than once with different argument lists. Instead, if you want to overload a method, you have to fake the compiler out and handle things yourself.
The example I'm going to show will overload methods by modifying the argument list in 2 ways. One way overloads a method by changing the type of the parameters in the argument list. The other way overloads a method by changing the length of the argument list. You can also change the types and the length to overload a method, but that is not illustrated here (though I've commented where to do such a thing).
Copy and paste this code into "OverloadTest.as"
class OverloadTest {
// Public method that is overridden to allow an argument that is either a string
// or a number. Note that we declare o as Object, not as Number or String.
public function overloadedMethod1(o:Object) {
// figure out what the type of o actually is and call our
// private helper function based on that
if (typeof (o) == "string") {
overloadedMethod1_str(o);
} else if (typeof (o) == "number") {
overloadedMethod1_num(o);
} else {
// run-time error checking, invalid type
// for now I'll just trace the output
trace("overloadedMethod1 invalid type " + typeof(o));
// it would be preferable to throw an exception here, but explaining
// this line is beyond the scope of this entry..
//throw new Error("overloadedMethod1 invalid type " + typeof(o));
}
}
// Private helper function to handle the dirty work of overloadedMethod1
// if called with a number. Note that n is declared as type Object here as
// well, and not Number. This is so the compiler doesn't complain about line
// 8, above.
private function overloadedMethod1_num(n:Object):Void {
trace("number - " + n);
}
// Private helper function to handle the dirty work of overloadedMethod1
// if called with a string. Note that n is declared as type Object here as
// well,and not Number. This is so the compiler doesn't complain about line
// 10, above.
private function overloadedMethod1_str(s:Object):Void {
trace("string - " + s);
}
// Public method that is overridden by specifying a different # of arguments
public function overloadedMethod2(n:Number, s:String) {
// figure out how many parameters we were passed in
// by arguments.length, and call the appropriate
// helper by the function.apply()... the help panel has
// good documentation about this.
this["overloadedMethod2_args"+arguments.length].apply(this, arguments);
}
// Private helper function to handle the dirty work of overloadedMethod2
// if called with 0 arguments
private function overloadedMethod2_args0():Void {
trace("0 args");
}
// Private helper function to handle the dirty work of overloadedMethod2
// if called with 1 argument
private function overloadedMethod2_args1(n:Number):Void {
trace("1 args - " + n);
}
// Private helper function to handle the dirty work of overloadedMethod2
// if called with 2 arguments
private function overloadedMethod2_args2(n:Number, s:String):Void {
trace("2 args - " + n + " | "+s);
// If you wanted to overload this method as well you would declare
// n and s as type Object and figure out what type they were here
// in the body of this function.. then you could call the appropriate
// helper function such as "overloadedMethod2_args2_date_string"
// if the first argument was a date and the second a string, or
// "overloadedMethos2_args2_num_str" if the first argument was a number
// and the second a string.
}
}
Then open up a new .fla and copy and paste this code on frame 1. This is how you would use the class defined above:
var t:OverloadTest = new OverloadTest();
// illustrate different arg types
t.overloadedMethod1("test 1");
t.overloadedMethod1(123);
// illustrate different # of args
t.overloadedMethod2();
t.overloadedMethod2(123);
t.overloadedMethod2(123, "test 2");
Note that the private helper functions cannot be called by the variable t because the "private" key word hides the functions from the user of the class. Private functions are meant to be strictly internal. There are workarounds for this in Flash since the private type checking is only done at compile time, but I won't discuss them here. Again, this is just another illustration of "information hiding" at work.
Additionally, if you want to test for types that you've created on your own (instead of the built-in types), you would have to use "instanceof" instead of "typeof" as "typeof" only returns the following information: "string", "movieclip", "object", "number", "boolean", and "function". An example of using instanceof looks like this:
// assume MySuperNumber is a class that has been created
var num:MySuperNumber = new MySuperNumber();
if (num instanceof MySuperNumber) {
// this statement will be executed in this example
trace("Of course num is an instance of MySuperNumber!!");
}
There are probably better ways of determining which type was passed into the function. I'm doing things the brute force comparison way, which isn't very elegant. Right now the worst case for a single argument being overloaded is N additional comparisons, where N is the number of possible types for an overloaded method. Performance gets worse the more you overload. To see the full discussion of this topic on FlashCoders, follow this link.

1 Comment
even though the overloading methods as described above is not exactly as it is mentioned above, but this piece of Pseudo Overloading methods is surely useful.
Posted by: chetan | December 1, 2003 1:14 AM