PDA

View Full Version : Extend array class


The Little Guy
01-30-2009, 09:23 PM
I am trying to extend the array class.

In my fla I have this:
var myArr:Array = new Array('1','2','3');

myArr.implode(myArr,';');

And my class looks like this:
package{
import Array;
public class Array extends Array{
public var str:String = '';
public function implode(arr:Array, sep:String):String{
for(var i:int=0;i<arr.length;i++){
str += arr[i].toString()+sep;
}
return str;
}
}
}

When I run it, I get this:

1113: Circular type reference was detected in Array.

How can I fix that?

senocular
01-30-2009, 09:25 PM
By naming your class something other than Array ; )

The Little Guy
01-30-2009, 09:29 PM
OK, so how would you make an array in the fla file?

senocular
01-30-2009, 09:32 PM
An array or your extended array? An array would be the same. Your extended array would be based on whatever you named it.

The Little Guy
01-30-2009, 09:33 PM
basically my goal is, is to extend the Array class so there are more functions to use in that class.

senocular
01-30-2009, 09:39 PM
AS3 doesn't really allow you to do that. Class definitions are static and if you need to add functionality, you would create a new class based off the existing class.

That being said, there is a workaround using the Ecmascript prototype. This is basically the AS1 approach to adding functionality to a class definition:
Array.prototype.newMethod = function() { ... }
But this is not recommended nor very standard.

lordofduct
01-30-2009, 09:40 PM
You have to call it something else then "Array".

Like Sprite extends DisplayObject

you can't call your new class the same thing as the class you're extending.

The Little Guy
01-30-2009, 09:46 PM
OK, I renamed it to ArrayExtra I would like to grab one of the functions from it, but I am not sure how...

I have this:
var myArr:Array = new Array('1','2','3');

myArr.implode(myArr,';');

But since implode isn't apart of the Array class, I would like to extend the Array class so the implode now becomes apart of that class now. So how can I do that?

senocular
01-30-2009, 10:14 PM
As I said before, to use your custom class, you would have to create an instance of it by its own name, i.e.
var myArr:ArrayExtra = new ArrayExtra();

The only way to actually modify Array itself is to do it how I suggested above.

The Little Guy
01-30-2009, 10:17 PM
according to Adobe, you can extned the class:

You can extend the Array class and override or add methods. However, you must specify the subclass as dynamic or you will lose the ability to store data in an array.

wvxvw
01-30-2009, 10:20 PM
Maybe you could just use Array.join()? Why do you need to reinvent the wheel, but make it a square?

EDIT:
according to Adobe, you can extned the class:
You misinterpret what it says. It means that you may create the class that is an Array + your custom features. But it doesn't mean that you can modify the Array class. Though, technically, you can modify the Array class by using ES prototype inheritance style, but this approach is really undesirable.

senocular
01-30-2009, 10:24 PM
according to Adobe, you can extned the class:

Yes, which is exactly what you were doing with ArrayExtra. Extending means creating a new class (with a different name) which is based off of, and inherits the functionality of, another base class, in this case Array.

And of course wvxvw's observation is quite astute : D

The Little Guy
01-30-2009, 10:24 PM
this is just a test to get this simple function to work, so I can extend it more.

The Little Guy
01-30-2009, 10:36 PM
Alright Thanks guys I got it working, not the way I was hoping, but it works.

worthyashes
01-30-2009, 10:41 PM
Ok, well if your heart set on it here's an example of an extension to the array class that works


package
{
public dynamic class ArrayExtra extends Array
{
public var str:String = '';

public function ArrayExtra(numElements:int=0)
{
super(numElements);
}

public function implode(arr:Array, sep:String):String{
for(var i:int=0;i<arr.length;i++){
str += arr[i].toString()+sep;
}
return str;
}
}
}


And using a main class called AS3Sketch (Sketch Pad I use to try things out) to run it : -


package {
import flash.display.Sprite;

public class AS3Sketch extends Sprite
{
public function AS3Sketch()
{
var arr:Array = new ArrayExtra();
arr.push("hello");
arr.push("world");
trace(arr.implode(arr,"::"));
}
}
}


Will trace 'hello::world::'

However if you want to do actions on an array then probably a more extendible version would to be to create a class that acts upon an Array


package
{
public class ArrayUtils
{
public function ArrayUtils()
{
}

public static function implode(arr:Array, sep:String):String{
var str:String = new String();
for(var i:int=0;i<arr.length;i++){
str += arr[i].toString()+sep;
}
return str;
}
}
}


And call it like this


package {
import flash.display.Sprite;

public class AS3Sketch extends Sprite
{
public function AS3Sketch()
{
var arr:Array = new Array();
arr.push("hello");
arr.push("world");
trace(ArrayUtils.implode(arr,"@@"));
}
}
}


Which'll trace 'hello@@world@@'

It's difficult without context, but if all you want to do is extend the array class make sure it's dynamic and public.

senocular
01-30-2009, 10:57 PM
Note that to follow the constructor behavior of Array, you would want to use something like the following:
public function Array(...values){
if (values.length == 1 and values[0] is Number){
super(values[0]);
}else{
push.apply(this, values);
}
}

worthyashes
01-30-2009, 11:12 PM
Interesting - I just extended the array class using flex builder and it popped in the code I posted above. Someone at Adobe should be told..... ;)

timo888
01-25-2010, 03:11 PM
in FB4 beta 2 the IDE automatically does this when you extend Array:

public dynamic class BetterArray extends Array
{
public function BetterArray(...parameters)
{
super(parameters);
}

}