ActionScript, ActionScript 3, Flash, Tutorials

Actionscript 3 Object Oriented Programming, implements Interface vs extends Class

Partiamo da qui:
Actionscript 3 rispetto ai suoi predecessori fa un balzo clamoroso verso l’OOP (object oriented programming) “vero”.

In un linguaggio Object Oriented il codice viene organizzato appunto in “oggetti”, ossia contenitori di funzionalit√† con metodi e propriet√† definite.

Ora, per comprendere meglio cosa significhi in AS3 questa affermazione procediamo ad esempi.

Immaginiamo un nostro “mondo” da codificare, un esempio potrebbero essere le persone…

Creiamo quindi una classe “Human” come segue:

public class Human
{
	public var sex :String;
	public var name : String;
	public var age : Number;
	public var height : Number;
	public var weight : Number;

	public function Human(strName:String, strSex:String)
	{ /* nascita + assegna nome + setta age=0 + assegna sesso (costruttore)*/ }

	public function compleanno() : void
	{ /* invecchia (age++) */  }

	public function morte() : void
	{ /* morte */  }

	public function respira() : void
	{ /* respira continuamente */ }
}

Extend
Nella classe “Human” abbiamo stabilito delle “propriet√†” e delle “funzionalit√†” che caratterizzano tutti gli esseri umani.
Ora cerchiamo di capire come lavorare la classe in termini di OOP e proviamo a capire il concetto di ereditarietà delle classi.

Creiamo 2 classi partendo da, o meglio estendendo Human:

public class Man extends Human
{
	public function Man(strName:String)
	{ super(strName,"M"); }
}

public class Woman extends Human
{
	public function Woman(strName:String)
	{ super(strName,"F"); }

	public function parto():void
	{ /* crea un nuovo human */ }
}

Le due classi Man e Woman ereditano dalla classe estesa Human tutte le sue funzionalit√† e propriet√† e ne possono aggiungere delle altre, ad esempio Woman ha a disposizione tutti i metodi di Human con l’aggiunta del metodo “parto”.

E’ possibile usare anche la keyword override per sovrascrivere uno stesso metodo in una classe estesa. Mi spiego meglio, se volessi modificare la frequenza di respirazione di un’istanza della classe “Man” dovrei ridichiarare all’interno della classe Man la funzione “respira” gi√† presente in Human, cos√¨ facendo Human manterr√† invariata la funzione respira e Man (e le sue eventuali sottoclassi) erediterebbero la funzione sovrascritta.

override public function respira() : void
{ /* cambia frequenza di respirazione */ }

Seguendo questa logica di programmazione la classe che ne estende un’altra √® a sua volta un membro della classe estesa. Questo significa che ad esempio ad una funzione che accetta come input un valore di tipo Human √® possibile passare un valore di tipo Man o Woman in quanto Man e Woman estendono Human e ne ereditano propriet√† e metodi.

Interface
Un’altra logica di programmazione per ottenere un simile risultato √® l’ottica delle interfacce.
Un’interfaccia √® una serie di regole alle quali le classi che la implementano si devono attenere.
Un’interfaccia non definisce del codice vero e proprio, definisce piuttosto i contenitori che dovranno essere riempiti dal codice.
Torniamo all’esempio della classe Human.
Se pensassimo alla classe Human di prima come interfaccia avremmo questo:

public interface IHuman
{
	function compleanno() : void
	function morte() : void
	function respira() : void
}

L’interfaccia IHuman (√® buona norma mettere una “I” davanti alle interfacce…non cambia nulla, ma almeno vi capite) comprende le definizioni dei metodi delle classi che andranno ad implementarla.

Ma come si implementa un’interfaccia?
Tornando all’esempio di prima:

public class Man implements IHuman
{
	private const sex :String = "M";
	private var age : Number;

	public function compleanno() : void
	{ /* invecchia (age++) */  }

	public function morte() : void
	{ /* morte */  }

	public function respira() : void
	{ /* respira continuamente */ }
}

“Man” implementa l’interfaccia IHuman, quindi se una funzione chiedesse in input un valore di tipo IHuman accetterebbe anche Man senza problemi.
Ma se creassimo un’altra classe “Woman” che implementi IHuman, che rapporto avrebbe questa con la classe Man?
Nel caso di extend le classi Man e Woman ereditavano gli stessi metodi e propriet√† dalla classe Human. Nel caso delle interfacce la logica cambia quasi radicalmente. Tutte le classi che implementano una stessa interfaccia devono soddisfare le dichiarazioni fatte nell’interfaccia stessa, devono quindi “riempire” con del codice i “contenitori” definiti nell’interfaccia, tuttavia il codice delle singole classi non √® in alcun modo legato n√® all’interfaccia n√® alle altre classi che la implementano. Questo significa che la funzione “morte” di Man pu√≤ fare cose completamente diverse dalla funzione con lo stesso nome presente in una classe “Woman” che sta implementando la stessa interfaccia.

Combinare Extend Class e Implement Interface
Non va dimenticato che una via non esclude l’altra. Si possono combinare le logiche di interfacce ed estensioni di classe per soddisfare le proprie esigenze.
Ad esempio potrebbe essere opportuno creare un’interfaccia Human implementata dalla classe Man a sua volta estesa dalla classe Boy.
Boy in questo caso avrebbe tutti i metodi presenti in IHuman ed erediterebbe tutte le propriet√† di Man, inoltre sarebbe membro sia dell’interfaccia IHuman che della classe Man e soddisferebbe entrambi i tipi richiesti da un’eventuale funzione.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s