A classe Array é uma das poucas classes principais que não é final, ou seja, você pode criar sua própria subclasse de Array. Esta seção mostra um exemplo de como criar uma subclasse de Array e discute alguns problemas que podem ocorrer durante o processo.
Como mencionado anteriormente, as matrizes no ActionScript não são tipificadas, mas é possível criar uma subclasse de Array que aceita elementos somente de um tipo de dados específico. O exemplo das seções a seguir define uma subclasse de Array chamada TypedArray que limita seus elementos aos valores do tipo de dados especificado no primeiro parâmetro. A classe TypedArray é apresentada simplesmente como um exemplo que mostra como estender a classe Array e talvez não seja adequada para fins de produção por diversos motivos. Primeiro, a verificação de tipo ocorre durante o tempo de execução, não no tempo de compilação. Segundo, quando um método TypedArray encontra uma discordância, esta é ignorada e nenhuma exceção é lançada, embora os métodos possam ser facilmente modificados para lançar exceções. Terceiro, a classe não pode impedir o uso do operador de acesso à matriz para inserir valores de qualquer tipo na matriz. Quarto, o estilo de codificação favorece a simplicidade por meio da otimização do desempenho.
Nota: Você pode usar a técnica descrita aqui para criar uma matriz tipificada. No entanto, recomenda-se o uso de um objeto Vector. Uma ocorrência de Vector é uma matriz true type e fornece desempenho e outros aprimoramentos em relação à classe Array ou qualquer subclasse. O objetivo desta discussão é demonstrar como criar uma subclasse Array.
Declaração da subclasse
Use a palavra-chave extends para indicar que uma classe é subclasse de Array. Uma subclasse de Array deve usar o atributo dynamic, assim como a classe Array. Caso contrário, a subclasse não funcionará adequadamente.
O código a seguir mostra a definição da classe TypedArray, que contém uma constante para armazenar o tipo de dados, um método de construtor e os quatro métodos que permitem adicionar elementos à matriz. O código de cada método é omitido neste exemplo, mas é descrito e explicado em detalhes nas seções a seguir:
public dynamic class TypedArray extends Array
{
private const dataType:Class;
public function TypedArray(...args) {}
AS3 override function concat(...args):Array {}
AS3 override function push(...args):uint {}
AS3 override function splice(...args) {}
AS3 override function unshift(...args):uint {}
}
Os quatro métodos de substituição usam o espaço para nomes AS3 em vez do atributo public porque este exemplo supõe que a opção -as3 do compilador está definida como true e a opção -es está definida como false. Essas são as configurações padrão do Adobe Flash Builder e do Adobe® Flash® Professional.

Se você for um desenvolvedor experiente que prefere usar protótipos herdados, faça duas pequenas alterações na classe TypedArray para compilá-la com a opção
-es do compilador definida como
true. Primeiro, remova todas as ocorrências do atributo
override e substitua o espaço para nomes AS3 pelo atributo
public. Segundo, substitua
Array.prototype nas quatro ocorrências de
super.
construtor TypedArray
O construtor de subclasse cria um desafio interessante porque aceita uma lista de argumentos de comprimento arbitrário. O desafio agora é transmitir os argumentos para o superconstrutor a fim de criar a matriz. Se você transmitir a lista de argumentos como uma matriz, o superconstrutor irá considerá-la como um único argumento do tipo Array e a matriz resultante terá sempre um elemento. O modo tradicional de manipular a transmissão de listas de argumentos é usar o método Function.apply(), que trata uma matriz de argumentos como seu segundo parâmetro, mas a converte em uma lista de argumentos ao executar a função. Infelizmente, o método Function.apply() não pode ser usado com construtores.
A única opção restante é recriar a lógica do construtor Array no construtor TypedArray. O código a seguir mostra o algoritmo usado no construtor da classe Array, que pode ser reutilizado no construtor da subclasse de Array:
public dynamic class Array
{
public function Array(...args)
{
var n:uint = args.length
if (n == 1 && (args[0] is Number))
{
var dlen:Number = args[0];
var ulen:uint = dlen;
if (ulen != dlen)
{
throw new RangeError("Array index is not a 32-bit unsigned integer ("+dlen+")");
}
length = ulen;
}
else
{
length = n;
for (var i:int=0; i < n; i++)
{
this[i] = args[i]
}
}
}
}
O construtor TypedArray compartilha a maior parte do código do construtor Array, com apenas quatro alterações no código. Primeiro, a lista de parâmetros inclui um novo parâmetro obrigatório de classe de tipo que permite especificar o tipo de dados da matriz. Segundo, a variável dataType é atribuída ao tipo de dados transmitido ao construtor. Terceiro, na instrução else, o valor da propriedade length é atribuído depois do loop for para que length inclua somente os argumentos do tipo correto. Quarto, o corpo do loop for usa a versão de substituição do método push() para que apenas os argumentos do tipo de dados correto sejam adicionados à matriz. O exemplo a seguir mostra a função do construtor TypedArray:
public dynamic class TypedArray extends Array
{
private var dataType:Class;
public function TypedArray(typeParam:Class, ...args)
{
dataType = typeParam;
var n:uint = args.length
if (n == 1 && (args[0] is Number))
{
var dlen:Number = args[0];
var ulen:uint = dlen
if (ulen != dlen)
{
throw new RangeError("Array index is not a 32-bit unsigned integer ("+dlen+")")
}
length = ulen;
}
else
{
for (var i:int=0; i < n; i++)
{
// type check done in push()
this.push(args[i])
}
length = this.length;
}
}
}
Métodos de substituição de TypedArray
A classe TypedArray substitui os quatro métodos da classe Array que permitem adicionar elementos a uma matriz. Em cada caso, o método de substituição adiciona uma verificação de tipo que impede a adição de elementos que não são do tipo de dados correto. Posteriormente, cada método chama sua própria versão de superclasse.
O método push() percorre a lista de argumentos com um loop for..in e faz uma verificação de tipo em cada argumento. Todos os argumentos que não são do tipo correto são removidos da matriz args com o método splice(). Quando o loop for..in termina, a matriz args contém valores somente do tipo dataType. A versão de superclasse de push() é chamada com a matriz args atualizada, como mostra o código a seguir:
AS3 override function push(...args):uint
{
for (var i:* in args)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
return (super.push.apply(this, args));
}
O método concat() cria uma matriz TypedArray temporária chamada passArgs para armazenar os argumentos aprovados na verificação de tipo. Isso permite a reutilização do código de verificação de tipo existente no método push(). O loop for..in percorre a matriz args e chama push() em cada argumento. Como passArgs é tipificada como TypedArray, a versão TypedArray de push() é executada. Em seguida, o método concat() chama sua própria versão de superclasse, como mostra o código a seguir:
AS3 override function concat(...args):Array
{
var passArgs:TypedArray = new TypedArray(dataType);
for (var i:* in args)
{
// type check done in push()
passArgs.push(args[i]);
}
return (super.concat.apply(this, passArgs));
}
O método splice() usa uma lista arbitrária de argumentos, mas os dois primeiros argumentos sempre fazem referência a um número de índice e ao número de elementos a serem excluídos. É por esse motivo que o método de substituição splice() executa a verificação de tipo somente para os elementos da matriz args nas posições de índice 2 ou superior. É interessante observar que o código parece ser uma chamada recursiva para splice() no loop for, mas não é porque args é do tipo Array e não TypedArray, o que significa que a chamada para args.splice() é uma chamada para a versão de superclasse do método. Quando o loop for..in termina, a matriz args contém apenas os valores do tipo correto nas posições de índice 2 ou superior e splice() chama sua própria versão de superclasse, como mostra o código a seguir:
AS3 override function splice(...args):*
{
if (args.length > 2)
{
for (var i:int=2; i< args.length; i++)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
}
return (super.splice.apply(this, args));
}
O método unshift(), que adiciona elementos ao início de uma matriz, também aceita uma lista arbitrária de argumentos. O método de substituição unshift() usa um algoritmo muito parecido com o usado pelo método push(), como mostra o exemplo a seguir:
AS3 override function unshift(...args):uint
{
for (var i:* in args)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
return (super.unshift.apply(this, args));
}
}