15. Membri statici


Attributi statici

Fino ad ora abbiamo visto che per utilizzare gli attributi e i metodi di una classe, è necessario creare un'istanza di tale classe, che viene poi usata per richiamare i membri attraverso l'operatore "." (punto).

ActionScript ci consente la gestione di tali attributi e metodi, senza alcuna necessità di allocare un'istanza, dichiarando questi membri come statici, ossia appartenenti solo alla classe e non alle istanze di questa.

Un attributo statico e un metodo statico possono essere paragonati rispettivamente ad una variabile e ad una funzione tradizionali, soggetti però ai vincoli di visibilità imposti dalla classe di appartenenza.

Per accedervi perciò è necessario specificare il nome della classe, seguito dall'operatore di selezione "." (punto).

Questo metodo può tornare utile quando, ad esempio, ci è necessario condividere un valore con tutte le istanze di una classe, e a questo proposito vedremo nell'esempio che segue, una classe DatiLogin che avrà due attributi statici che verranno utilizzati da tutte le istanze della suddetta classe, per verificare che il nome utente e la password usati abbiano una lunghezza minore o uguale alla massima consentita.

DatiLogin.as

package
{
	public class DatiLogin
	{
		// Lunghezza massima per il nome utente di 15 caratteri
		static public var nome_max_length:int = 15;
		// Lunghezza massima per la password utente di 20 caratteri
		static public var pass_max_length:int = 20;

		private var nome_utente:String;
		private var pass_utente:String;

		public function DatiLogin(nome:String, pass:String):void
		{
			if (nome.length <= DatiLogin.nome_max_length) this.nome_utente = nome;
			else throw new Error("Nome utente (" + nome + ") troppo lungo!");

			if (pass.length <= DatiLogin.pass_max_length) this.pass_utente = pass;
			else throw new Error("Password utente (" + nome + ") troppo lunga!");
		}

		public function connetti():void
		{
			/* Si connette ad un server utilizzando
			nome_utente e pass_utente per autenticarsi */
		}
	}
}

La classe dell'esempio soprastante è stata scritta per uno scopo puramente didattico.

Di seguito un esempio che mostra un uso ipotetico della classe DatiLogin.

HelloWorld.as

package
{
	import DatiLogin;
	import flash.display.MovieClip;

	public class HelloWorld extends MovieClip
	{
		public function HelloWorld():void
		{
			/* Reimpostiamo la lunghezza massima
			per il nome utente fino a 20 caratteri */
			DatiLogin.nome_max_length = 4;

			var loginSito1:DatiLogin = new DatiLogin("root", "cicciobello"); // Ok
			var loginSito2:DatiLogin = new DatiLogin("admin", "pippopluto"); // Errore
		}
	}
}

L'inizializzazione dell'istanza loginSito2 provoca un errore, perchè il nome utente "admin" è di 5 caratteri, mentre il massimo consentito è stato impostato a 4 attraverso la variabile statica "nome_max_length".

Ricordate che non potrete accedere ai membri statici attraverso le istanze, e neppure attraverso this dall'interno della classe, ma solo specificando il nome della classe come abbiamo visto nell'esempio precedente.

var login:DatiLogin = new DatiLogin("root", "password");

login.nome_max_length = 15; // Errore, operazione non consentita
DatiLogin.nome_max_length = 15; // Tutto Ok!

Metodi statici

Come ho anticipiato all'inizio, i metodi statici sono come delle funzioni tradizionali, ma vincolate dalle regole di visibilità ed accessibilità imposte dalla classe a cui appartengono.

Può essere necessario implementare un metodo statico in una classe, per fornire ad esempio un pseudo-costruttore che invece di inizializzare un nuovo oggetto, restituisce un'istanza di questa classe inizializzata a partire da un file XML esterno.

Segue una bozza di una classe d'esempio "Salvataggio", che disporrà di un metodo statico per caricare i salvataggi da un file esterno in formato XML.


Salvataggio.as

package
{
	public class Salvataggio
	{
		var partita:*;
		var data:Date;
		var giocatore:String;

		public function Salvataggio():void
		{
			// ...
		}

		static public function caricaDaXML(nome_file:String):Salvataggio
		{
			var save:Salvataggio = new Salvataggio();

			/* Apre e legge un file XML con i dati di gioco ed
			inizializza un'istanza di "Salvataggio" con questi dati */

			return save;
		}
	}
}

HelloWorld.as

package
{
	import Salvataggio;
	import flash.display.MovieClip;

	public class HelloWorld extends MovieClip
	{
		public function HelloWorld():void
		{
			var save:Salvataggio = Salvataggio.caricaDaXML("mario_01_save.xml");
		}
	}
}

Infine, i membri statici, non vengono eriditati dalle sottoclassi.