Teoria sulle classi
Questo è senzaltro uno dei capitoli essenziali della presente guida, dal momento che ActionScript 3 si è
evoluto, rispetto ai suoi predecessori, basandosi fortemente sulla programmazione orientata agli oggetti
(OOP).
La programmazione orientata agli oggetti è un metodo di sviluppo ormai
molto diffuso, poichè consente di
risparmiare molto tempo rendendo la scrittura del codice più intuitiva e l\'applicazione più robusta, accorciando le distanze fra la cruda
programmazione e il mondo reale.
In linea di massima e limitando molto il concetto, possiamo pensare ad un oggetto semplicemente come ad un nuovo
tipo di dato creato da noi, con particolari attributi e metodi per gestirlo.
Immaginiamo ora di dover scrivere un\'applicazione che disegna sullo stage un triangolo.
Per disegnare il triangolo innanzitutto ci saranno necessarie le coordinate dei suoi punti, ed essendo un triangolo ne avrà tre.
Con le nozioni apprese fino ad ora potremmo memorizzare questi dati all'interno di varibili o ancora meglio all'interno di un array.
Avendo ogni punto due coordinate (x e y) sarà quindi necessario un array di 6 elementi come mostrato di seguito :
function disegnaTriangolo(triangolo:Array):void
{ /* Codice per disegnare il triangolo */ }
var triangolo:Array = new Array();
triangolo["x1"] = 5;
triangolo["y1"] = 10;
triangolo["x2"] = 30;
triangolo["y2"] = 40;
triangolo["x3"] = 70;
triangolo["y3"] = 90;
disegnaTriangolo(triangolo);
L'esempio soprastante non è certo il migliore dei modi per gestire il problema proposto, soprattutto se supponiamo di dover disegnare
molti triangoli, il codice diventerebbe allora una lunga e pesante matassa di assegnazioni.
Iniziamo a dare una sfoltita al codice immaginando di poter creare il nuovo tipo di dato Punto.
Assieme a questa nuova classe potremmo, ad esempio, creare ancora un nuovo tipo che chiameremo
Triangolo, che avrà al suo interno tre variabili del tipo Punto.
Il codice si presenterebbe così :
var triangolo1:Triangolo = new Triangolo(new Punto(5, 10), new Punto(30, 40), new Punto(70, 90));
triangolo.disegna();
Il sorgente non è solo più pulito e intuitivo, ma il codice per definire le classi Punto e
Triangolo, sarà universale e potrete utilizzarlo per tutte le vostre applicazioni senza alcuna necessità di
riscriverlo.
I vantaggi che potrete trarre da questo metodo di programmazione sono innumerevoli, e vi saranno tutti molto più chiari man mano che
andrete avanti con la lettura, imparando a pensare alle vostre applicazioni direttamente come ad una serie di oggetti
in relazione fra loro.
Le classi in ActionScript 3
Le classi in ActionScript 3 devono avere obbligatoriamente un package di appartenenza,
concetto che illustrerò più avanti, intendendo per ora i package come dei semplici contenitori di classi.
Le classi dovranno essere scritte in file esterni con estensione .as.
Per farlo è sufficiente aprire il Blocco note e salvare i file con l'estensione specificata pocanzi, oppure tramite Flash
CS3 creando un nuovo File ActionScript (CTRL + N).
Per dichiarare una classe abbiamo a disposizione l'istruzione class :
package
{
public class MiaClasse
{
// Corpo della classe
}
}
|
| La parola chiave public è un modificatore di accesso, ed indica che la classe è accessibile anche
dall'esterno.
A questo punto per poter continuare a illustrare le classi, è necessario introdurre alcuni nuovi concetti.
Le classi non definiscono un tipo di dato comune, e per inizializzare correttamente la variabile che dovrà
contenere il nostro oggetto, è necessaria l'istruzione new, già vista in qualche esempio precedente.
La variabile che conterrà l'oggetto è detta istanza. |
var contenitore:MiaClasse = new MiaClasse();
Nell'esempio soprastante, "contenitore" è un'istanza della classe "MiaClasse".
Una classe può definire degli attributi e dei metodi, che sarà possibile richiamare attraverso un'istanza seguita
dall'operatore di selezione ".".
Potete pensare agli attributi (detti anche proprietà) come a delle variabili proprie
dell'oggetto, e potete pensare ai metodi come a delle funzioni proprie dell'oggetto.
Vediamo un esempio in cui dichiaro una classe Punto con due attributi x e
y e un metodo output :
package
{
public class Punto
{
var x:Number; // Attributo
var y:Number; // Attributo
function output():void // Metodo
{
trace("x = " + this.x);
trace("y = " + this.y);
}
}
}
In questo frammento di codice possiamo osservare una nuova istruzione : this.
this è una sorta di puntatore che ci consente di accedere agli attributi e ai metodi della classe, dall'interno di
quest'ultima.
Vediamo ora il codice che ci permetterà di utilizzare la classe inizializzandone un'istanza, e accedendo agli attributi mediante essa.
var p1:Punto = new Punto();
// Usiamo l'operatore di selezione "." per accedere agli attributi
p1.x = 10;
p1.y = 12;
// Chiamiamo il metodo dell'oggetto
p1.output();
L'output prodotto dal metodo output dell'istanza "p1" è il seguente :
In questo capitolo continueremo il discorso sulle classi, introducendo nozioni che ci consentiranno un controllo
maggiore e più efficace con questi strumenti.
Abbiamo visto come un metodo può gestire e manipolare gli attributi della classe a cui appartiene, agendo come
una vera e propria funzione, ma interna alla classe.
Costruttori
Esiste un metodo molto importante chiamato costruttore della classe.
Il costruttore verrà richiamato automaticamente ad ogni creazione di un'istanza, ed è possibile definirne uno
personalizzato.
Per dichiarare un costruttore è sufficiente dichiarare un normale metodo ma con lo stesso nome della classe :
Punto.as
package
{
public class Punto
{
/* Attributi */
var x:Number;
var y:Number;
/* Costruttore */
function Punto(nuova_x:Number, nuova_y:Number)
{
this.x = nuova_x;
this.y = nuova_y;
}
/* Metodo */
function output():void
{
trace("x = " + this.x);
trace("y = " + this.y);
}
}
}
Il costruttore, essendo un metodo, può prendere dei parametri alla stessa maniera di una funzione tradizionale.
Questi parametri saranno utilizzati in sostanza per inizializzare correttamente gli attributi della classe.
HelloWorld.as
package
{
import Punto;
import flash.display.MovieClip;
public class HelloWorld extends MovieClip
{
public function HelloWorld():void
{
var p1:Punto = new Punto(14, 65);
p1.output();
}
}
}
L'output prodotto dall'esempio soprastante (HelloWorld) è il seguente :
In ActionScript 3 è possibile assegnare dei particolari modificatori agli attributi di una classe, per assegnare ad essi
un determinato livello di accessibilità e visibilità.
I modificatori di accesso si specificano subito prima il nome dell'attributo o del metodo e ne esistono quattro :
- internal - Restringe la visibilità al pacchetto (package) di appartenenza
- public - I membri (attributi o metodi) dichiarati come public, saranno accessibili a tutte le classi e da
tutti i pacchetti visibili
- private - Questi membri possono essere utilizzati solo all'interno della classe madre
- protected - Restringe l'accesso solo all'interno della classe madre e alle classi derivate
|
| Se non viene specificato alcun modificatore di accesso, ActionScript utilizzerà di default il modificatore
internal.
Per fare un esempio, potremmo volere la certezza che le coordinate memorizzate nella classe Punto siano sempre dei
numeri, dando la possibilità all'utente che utilizza la classe di inizializzare le istanze anche con delle stringhe, utile quando i dati vengono
acquisiti da tastiera tramite ad esempio un campo di testo.
A questo scopo, potremmo rendere i due attributi x e y privati mediante il modificatore di accesso
private, consentendo la modifica di questi valori solo attraverso il costruttore, che sarà
progettato per effettuare sempre un casting esplicito al tipo Number. |
Punto.as
package
{
public class Punto
{
private var x:Number;
private var y:Number;
public function Punto(nuova_x:*, nuova_y:*)
{
this.x = new Number(nuova_x);
this.y = new Number(nuova_y);
}
public function output():void
{
trace("x = " + this.x);
trace("y = " + this.y);
}
}
}
Questo metodo ci consente di evitare assegnazioni di tipo non desiderato, ricevendo un errore 1178 nel caso in cui questo avvenga :
Tentativo di accesso alla proprietà non accessibile x mediante un riferimento con tipo statico Punto.
HelloWorld.as
package
{
import Punto;
import flash.display.MovieClip;
public class HelloWorld extends MovieClip
{
public function HelloWorld():void
{
var p1:Punto = new Punto("28.7", "68.4");
p1.output();
}
}
}
L'esempio soprastante produce il seguente output :