11

I want a function to be able to take in various types. AS3 doesn't support overloading directly... so I can't do the following:

//THIS ISN'T SUPPORTED BY AS3

function someFunction(xx:int, yy:int, someBoolean:Boolean = true){
    //blah blah blah
}
function someFunction(arr:Array, someBoolean:Boolean = true){
    someFunction(arr[0], arr[1], someBoolean);
}

How can I work around it and still have a function that is able to take arguments of various types?

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
AS3 Guy
  • 111
  • 1
  • 1
  • 3
  • I am sure you will get your answers, but I am just courious why you would want to use method overloading? I have sometimes gotten to a certain point when that really would have helped to fix a quick problem, but I concider it BAD PRACTICE so I dont do it. – Mattias Sep 19 '11 at 06:05
  • I agree with Mattias. W/o native support for overloading, it's bad practice to have a function accepting variable parameters (unless in very, very specific situations which have nothing to do with overloading) – Creynders Sep 19 '11 at 07:24
  • 5
    Method overloading is an incredibly handy addition to any language. It would make stuff like Math classes so much easier; no more multPoint(), multScalar() etc, you can just have mult() – divillysausages Sep 19 '11 at 07:31
  • @divillysausages Cool. Any good examples of that? – Mattias Sep 19 '11 at 07:53
  • it's not really supported in as3. the best i've seen is something like zzzzBov's answer: `function mult( param:* ):void { if (param is Point) this._multPoint(); else if (param is Number) this._multScalar(); }` – divillysausages Sep 19 '11 at 08:25
  • I agree with peeps above. Method Overloading with be amazing if native.. All "Hacks" for it are not worth the implementation time! – WORMSS Oct 03 '12 at 11:40

2 Answers2

21

If you just want to be able to accept any type, you can use * to allow any type:

function someFunction( xx:*, yy:*, flag:Boolean = true )
{
  if (xx is Number) {
    ...do stuff...
  } else if (xx is String) {
    ...do stuff...
  } else {
    ...do stuff...
  }
}

If you have a large number of various parameters where order is unimportant, use an options object:

function someFunction( options:Object )
{
  if (options.foo) doFoo();
  if (options.bar) doBar();
  baz = options.baz || 15;
  ...etc...
}

If you have a variable number of parameters, you can use the ... (rest) parameter:

function someFunction( ... args)
{
  switch (args.length)
  {
    case 2:
      arr = args[0];
      someBool = args[1];
      xx = arr[0];
      yy = arr[1];
      break;
    case 3:
      xx = args[0];
      yy = args[1];
      someBool = args[2];
      break;
    default:
      throw ...whatever...
  }
  ...do more stuff...
}

For cases where you need to call a common function to a number of classes, you should specify the interface common to each class:

function foo( bar:IBazable, flag:Boolean )
{
  ...do stuff...
  baz = bar.baz()
  ...do more stuff...
}
avanderw
  • 675
  • 1
  • 7
  • 22
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • As an ECMAScript variant, you can use the [same techniques as JavaScript](http://stackoverflow.com/a/10855947/497418). – zzzzBov Jun 19 '12 at 19:07
2

Could just have:

function something(...args):void
{
    trace(args[0], args[1]);
}

This way you can easily loop through your arguments and such too (and even check the argument type):

function something(...args):void
{
    for each(var i:Object in args)
    {
        trace(typeof(i) + ": " + i);
    }
}

something("hello", 4, new Sprite()); // string: hello
                                     // number: 4
                                     // object: [object Sprite]
Marty
  • 39,033
  • 19
  • 93
  • 162