sábado, 10 de maio de 2008

AS3 - static

Quando criamos novas instâncias de uma classe, elas têm acesso a métodos e propriedades da mesma. Porém, cada instância vai operar individualmente os valores de suas propriedades e métodos.
Por exemplo:

Teste.as


package
{
public class Teste
{
private var num:int = 0;

public function set setNum(n:int):void
{
num = n;
}

public function get seeNum():int
{
return num;
}
}
}


Testando.as

package
{
import flash.display.Sprite;

public class Testando extends Sprite
{
private var num1:Teste;
private var num2:Teste;

public function Testando()
{
num1 = new Teste();
num2 = new Teste();

//mostra os valores da propriedade "num" de cada instância
trace("Primeira mostra dos valores");
trace("num1.num = " + num1.seeNum);
trace("num2.num = " + num2.seeNum);

//alteramos o valor da propriedade "num" da primeira instância
num1.setNum = 10;

//mostra novamente os valores da propriedade "num" de cada instância
trace("\nSegunda mostra dos valores");
trace("num1.num = " + num1.seeNum);
trace("num2.num = " + num2.seeNum);
}
}
}


Neste exemplo, tanto num1 quanto num2, criadas dentro da classe Testando, são instâncias de uma mesma classe - Teste.
Quando traçado o valor retornado pelo método seeNum de cada instância, vemos os valor 0(zero) para cada uma. Isso porque a classe tem por definição este valor para a propriedade requisitada.

Em seguida alteramos o valor da propriedade para a instância num1 através do método setNum.Embora num1 agora tenha sua propriedade num com o novo valor, num2 permanece com o valor de sua propriedade inalterado. Vemos isso pelo segundo bloco traçado.

Onde entra o static nisso?

Veja bem. No exemplo acima vemos que as propriedades e métodos estão ligados as instâncias dessa classe. Elas operam esses valores individualmente. Porém, as vezes, precisamos construir um sistema onde, ao se alterar o valor de uma propriedade para uma das instâncias, todas as demais também tenham seus valores atualizados.
Para isso podemos contar com o atributo static.Quando se usa o atributo static na declaração de uma propriedade ou método, este passa a ser estático da classe.

No AS3 constantemente trabalhamos com métodos e propriedades estáticos, veja alguns deles:

Regular.easeOutText
FieldAutoSize.CENTER
MouseEvent.CLICK


Nos exemplos acima vemos propriedades e métodos definidos como estáticos dentro de suas respectivas classes.
Note que quando se declara um método estático não é preciso instanciar um objeto da classe para chamá-lo. O método é chamado usando o próprio nome da classe, bem como o valor de uma propriedade.

Tudo isto está na sua cabeça como um balaio de gatos?
Vamos então exercitar isso com um exemplo para ver se clareiam as coisas.
Para isto vamos construir uma classe que será responsável por gerar um Sprite, um "quadradinho" clicável.
Noutra classe vamos controlar nosso filme e teremos também mais um arquivo .fla por onde vamos compilar tudo isso.

Mãos a obra!


teste.fla

Abra o Flash CS3 e crie um novo documento do tipo Flash File(ActionScript 3.0).Abra o painel de propriedades e no campo Document Class digite Controle.

Salve o filme com o nome de teste.fla e deixe ele aberto aí quietinho.



MeuSprite.as

Crie um novo documento, só que agora é do tipo ActionScript File.
Cole este código nele:

package
{
import flash.display.Sprite;
import flash.events.MouseEvent;

public class MeuSprite extends Sprite
{
private static var lista:Array = new Array();
private var sprite:Sprite;

public function MeuSprite()
{
sprite = novo();
addSprite();
addChild(sprite);
}

private function novo():Sprite
{
var sprite = new Sprite();
sprite.graphics.beginFill(0x007700);
sprite.graphics.moveTo(10,10);
sprite.graphics.drawRect(-10, -10, 20, 20);
sprite.graphics.endFill();
sprite.x = Math.random() * 500 + 20;
sprite.y = Math.random() * 400 + 20;
sprite.addEventListener(MouseEvent.MOUSE_DOWN, gira);
return sprite;
}

private function addSprite():void
{
lista.push(sprite);
}

private function gira(event:MouseEvent):void
{
event.target.rotation += 45;
}

public static function giraTodos():void
{
for each (var o:Object in lista)
{
o.rotation += 45;
}
}
}
}

Salve este arquivo como o nome de MeuSprite.as na mesma pasta onde salvou o arquivo .fla

Nesta classe quando o construtor é chamado, um novo Sprite é desenhado e adicionado. Também é inserido numa lista(Array).
Cada instância dessa classe tem um ouvinte de evento para que, ao se pressionar o mouse sobre o mesma, ela gire 45 graus.

Note que o último método(giraTodos) possui o atributo static. Ele pega todos os objetos que estiverem dentro da lista e gira em 45 graus cada um deles. lista também é estática, pois não podemos ter nela um valor que varie de acordo com cada instância.

Para vermos o funcionamento disso vamos criar mais uma classe.



Controle.as

package
{
import flash.display.Sprite;
import flash.events.KeyboardEvent;

public class Controle extends Sprite
{
private var meuSprite:MeuSprite;

public function Controle()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, opera);
}
private function opera(event:KeyboardEvent):void
{
if (event.keyCode == 32)
{
meuSprite = new MeuSprite();
addChild(meuSprite);
}
if (event.keyCode == 71)
{
MeuSprite.giraTodos();
}
}
}
}


Salve, também na mesma pasta, com o nome de Controle.as.


Nesta segunda classe, que é a classe que definimos para o arquivo .fla, adicionamos um ouvinte de evento para stage.

O ouvinte chama o método opera. Neste é criada uma nova instância da classe MeuSprite caso a tecla pressionada seja a barra de espaço. Ao mesmo tempo, a propriedade lista, estática da classe MeuSprite, ganha um registro.

Caso a tecla pressionada seja a letra "G", é chamado o método estático da classe MeuSprite - giraTodos().
Este método independe de haver ou não uma instância de classe para que possa ser chamado.

Teste o filme para ver o resultado.


Pressione a barra de espaço para adicionar alguns objetos na tela.

Quando você clica em cada um deles, eles giram individualmente.
Porém quando você pressiona a tecla "G" todos giram.

Isto acontece porque você está chamando o método estático da classe, e este, independentemente de quantas instâncias houver, vai pegar o valor da propriedade estática lista. Esta lista possui todos os objetos instanciados e opera como sendo uma propriedade da classe e não da instância, mesmo ela tendo o seu valor alterado por um método ligado a instância.


---

Nenhum comentário: