L'ereditarietà è uno dei concetti base su cui poggia uno dei paradigmi di programmazione più usati dalle
applicazioni moderne, la programmazione orientata agli oggetti, che abbiamo già avuto modo di conoscere nel
precedente capitolo sulle classi :
Classi
Questo metodo di programmazione ci consente di sfruttare appieno le potenzialità di questo paradigma per i seguenti motivi :
ActionScript 3 ci consente di creare una sottoclasse derivata da un'altra mediante la direttiva extends,
come mostrato nell'esempio seguente.
Unita.as - Classe Base
package
{
public class Unita
{
protected var attacco:uint;
protected var difesa:uint;
protected var distanza:uint;
protected var velocita:uint;
public function Unita():void
{ /* ... Costruttore ... */ }
}
}
Fante.as - Classe Derivata
package
{
import Unita;
public class Fante extends Unita // "Fante" eredita da "Unita"
{
protected var puntiferita:uint;
public function Fante():void
{
this.attacco = 10;
this.difesa = 20;
this.distanza = 1;
this.velocita = 5;
this.puntiferita = 100;
}
}
}
Come possiamo notare dall'esempio soprastante, la classe "Fante" eredita i quattro attributi
protected dichiarati nella classe "Unita".
Nota : protected è un modificatore di accesso che restringe la visibilità dei
membri alla sola classe base ed alle sue derivate.
Nell'esempio soprastante, abbiamo esteso il codice senza effettuare alcuna modifica alla
classe esistente "Unita", ma semplicemente creando una classe specializzata per rappresentare il nuovo
tipo di dato "Fante" con un attributo aggiuntivo.
Un altro strumento che l'ereditarietà ci mette a disposizione è la possibilità di ridefinire alcuni
elementi delle classi base.
Molti linguaggi ci consentono di ridefinire sia gli attributi che i metodi di una classe, mentre ActionScript 3 ci permette
di ridefinire solo i metodi, lasciando tutti gli attributi e le costanti delle classe base (var e const) come proprie di quest'ultima.
E' comunque possibile ridefinire gli attributi attraverso la definizione dei metodi speciali get e
set che abbiamo visto nel capitolo precedente. |
|
Ridefinizione dei Metodi
Per ridefinire un metodo in ActionScript 3, si usa la direttiva override seguita dalla dichiarazione
del metodo, che dovrà rispecchiare esattamente la struttura del metodo base o il compilatore restituirà il messaggio "Override incompatibile".
Questo significa che se il metodo base prende un determinato numero di parametri di un tipo stabilito, il metodo che andrà a ridefinirlo
dovrà prendere gli stessi parametri dello stesso tipo.
Un metodo sarà ridefinibile solo se dichiarato pubblico, protetto o interno.
Se dichiarato privato sarà comunque possibile definire un metodo con lo stesso nome nella classe derivata, in quanto il metodo della
classe base non sarà visibile all'esterno (private), e procederemo quindi senza la direttiva override.
Di seguito un semplice esempio dove ridefiniremo il metodo "muovi()" :
Unita.as - Classe Base
package
{
public class Unita
{
protected var attacco:int;
protected var difesa:int;
protected var distanza:int;
protected var velocita:int;
public function Unita():void
{ /* ... Costruttore ... */ }
public function muovi(passi:uint):void
{
/* Sposta l'unita di N passi */
trace("Chiamata a 'Unita.muovi()'");
}
}
}
Fante.as - Classe Derivata
package
{
import Unita;
public class Fante extends Unita
{
public function Fante():void
{
this.attacco = 10;
this.difesa = 20;
this.distanza = 1;
this.velocita = 5;
}
override public function muovi(passi:uint):void
{
trace("Chiamata a 'Fante.muovi()'");
}
}
}
HelloWorld.as - Classe documento
package
{
import Fante;
import flash.display.MovieClip;
public class HelloWorld extends MovieClip
{
public function HelloWorld():void
{
var soldato:Fante = new Fante();
soldato.muovi(10); // Output : Chiamata a 'Fante.muovi()'
}
}
}
Se non avessimo effettuato un override nella classe Fante, la chiamata al metodo
"muovi()" avrebbe provocato il seguente output :
Chiamata a 'Unita.muovi()'
|
| Metodo super
Potrebbe capitare durante l'implementazione di un override, di non voler riscrivere completamente il metodo base
ma di volergli solo aggiungere qualche funzionalità.
In questo caso ci sarà di aiuto lo speciale metodo super, attraverso cui ci sarà possibile accedere direttamente
alle proprietà (attributi e metodi) della classe base, da una sua derivata.
Nel prossimo esempio riscriverò solo la classe Fante, lasciando i file Unita.as
e HelloWorld.as invariati : |
Fante.as - Classe Derivata
package
{
import Unita;
public class Fante extends Unita
{
public function Fante():void
{
this.attacco = 10;
this.difesa = 20;
this.distanza = 1;
this.velocita = 5;
}
override public function muovi(passi:uint):void
{
super.muovi(passi * this.velocita);
trace("Chiamata a 'Fante.muovi()'");
}
}
}
Richiamando la classe documento HelloWorld si ottiene il seguente output :
Chiamata a 'Unita.muovi()'
Chiamata a 'Fante.muovi()'
Nota : vengono ereditati tutti i membri che non sono private e statici.