Suggerendoti di pensare agli insiemi delle scuole dell’infanzia, stavamo effettivamente introducendo, se vogliamo, il concetto di classe.
Le classi, nei linguaggi di programmazione in generale, ma in questa sede in PHP , ci consentono, infatti, di fare una classificazione di elementi che, nella nostra realtà, hanno delle caratteristiche in comune. Non molto distanti dagli insiemi di cui sopra, giusto?
Caratteristiche comuni, dunque, fanno in modo che un dato elemento appartenga ad un insieme e non ad un altro.
Pensaci bene: viviamo ogni giorno, nella nostra quotidianità, Il concetto di classe e classificazione, quando andiamo a raggruppare degli elementi tenendo conto delle loro caratteristiche più evidenti: nell’armadio riporremo tutti i vestiti, nel frigorifero tutti gli alimenti e così via.
Immaginando un gruppo di persone, per esempio, sicuramente potremo trovare degli elementi in comune tra tutti loro: il nome, il cognome o l’età, per citarne alcuni.
“Persona”, quindi, potrebbe diventare un ottimo esempio per definire una classe; nome, cognome ed età, invece, rappresenteranno le caratteristiche di una persona, comuni a tutte le persone.
CLASSI PHP: LA SINTASSI
Nel linguaggio PHP una classe si definisce tramite la keyword class e con il suo nome, che, però, deve rispettare determinate regole:
- Dev’essere in inglese;
- Deve avere la lettera iniziale maiuscola;
- Dev’essere al singolare.
<?php class Person {} ?>
Vediamo l’anatomia di una classe.
Una classe, al suo interno, è composta da tre parti principali:
- Gli attributi o proprietà;
- Una funzione costruttore;
- I metodi o comportamenti.
GLI ATTRIBUTI IN PHP
Gli attributi sono quelle caratteristiche che accomunano tutti gli appartenenti a quella classe e si dichiarano all’inizio della stessa.
Abbiamo detto, precedentemente, che ogni persona è caratterizzata da un nome, un cognome e un’età. Tradurremo in codice in questo modo:
<?php class Person { public $name; public $surname; public $age; } ?>
Come vedi, abbiamo specificato che ogni oggetto della classe Person avrà quelle determinate caratteristiche (o attributi).
La classe, scritta in questo modo, tuttavia, è incompleta, in quanto non abbiamo la possibilità di creare degli oggetti da essa. Ma che cos’è un oggetto?
Per oggetto si intende un’istanza appartenente a una classe specifica, ovvero un dato che durante l’esecuzione di un programma è presente nella memoria del nostro pc come entità.
E’ per questo che abbiamo bisogno di una funzione particolare nota come funzione costruttore, il cui compito sarà prendere in ingresso degli argomenti reali e assegnarli all’istanza che stiamo creando.
Vediamolo in codice:
<?php class Person { public $name; public $surname; public $age; public function __construct($name, $surname, $age){ $this->name = $name; $this->surname = $surname; $this->age = $age; } } $persona = new Person(‘Giuseppe’, ‘Verdi’, 56); ?>
In questo modo, abbiamo specificato al nostro algoritmo come i dati “Giuseppe” “Verdi” “56” debbano andare a creare l’istanza di classe Person che salveremo in $persona.
Analizziamo, però, la funzione costruttore:
- Il suo nome deve essere necessariamente “__construct”, altrimenti non sarà riconosciuta come costruttore. Infatti, questa funzione viene richiamata quando l’algoritmo incontra la keyword new appaiata al nome di una classe;
- Essendo una funzione, il costruttore accetta dei parametri in ingresso, che ricordiamo essere formali, che altro non saranno che i nostri attributi;
- Importantissima è la pseudo-variabile $this che sta a indicare l’oggetto che andremo a creare. Infatti, non dobbiamo mai dimenticare che noi stiamo creando, tramite la classe, una mera descrizione e non un oggetto effettivo.
In soldoni, stiamo dicendo alla funzione che, dell’oggetto della classe Person che andremo a creare, dovrà catturare l’argomento reale ricevuto nel costruttore e valorizzarne l’attributo assegnato.
Adesso siamo in grado di creare illimitate istanze della classe Person, ma un oggetto così costruito è ancora poco efficace.
Come detto in precedenza, una classe può avere anche dei metodi o comportamenti ad essa legati.
METODI O COMPORTAMENTI
Una persona compie, nella sua quotidianità, una quantità infinita di azioni che noi possiamo racchiudere e descrivere attraverso quelli che chiamiamo metodi o comportamenti.
Un esempio comune è la possibilità per una persona di presentarsi. Andiamo a vedere come tradurre questo comportamento, appunto, in codice:
<?php class Person { public $name; public $surname; public $age; public function __construct($name, $surname, $age){ $this->name = $name; $this->surname = $surname; $this->age = $age; } public function presentati( ){ echo “Ciao, sono $this->name $this->surname e ho $this->age anni.\n”; } } $persona = new Person(‘Giuseppe’, ‘Verdi’, 56); $persona->presentati( ); //Output //Ciao, sono Giuseppe Verdi e ho 56 anni. ?>
La funzione presentati( ) è un metodo che permette a tutte le istanze di classe Person di presentarsi e mostrare tutti i valori relativi ai loro attributi. Non è diversa dalle funzioni che abbiamo presentato nel capitolo dedicato.
Osserva la sintassi. Cosa noti?
Tramite la freccia, non facciamo altro che entrare nell’oggetto specificato ($persona) e catturare ciò che segue (il metodo presentati(), nel nostro caso).
Questo tipo di sintassi ci permette di accedere a tutti gli elementi di un’istanza, che si tratti di metodi o di attributi.
<?php class Person { //attributi public $name; public $surname; public $age; //costruttore public function __construct($name, $surname, $age) { $this->name = $name; $this->surname = $surname; $this->age = $age; } //metodo public function presentati(){ echo "Ciao, sono $this->name $this->surname ed ho $this->age anni.\n"; } } $persona = new Person('Giuseppe','Verdi','56'); echo $persona->name; //Output //Giuseppe ?>
Anche in questo caso, l’utilizzo della pseudo-variabile $this si riferisce all’oggetto che andremo a creare, sempre per lo stesso concetto che con la classe non creiamo nulla ma andiamo solo a descrivere qualcosa.
ATTRIBUTI E METODI STATICI
Altri elementi molto utilizzati nella programmazione ad oggetti sono quei metodi e attributi definiti statici.
Per definizione, gli attributi e metodi statici non agiscono per conto di un oggetto ma direttamente per conto di una classe. Cosa vuol dire?
La definizione ci indica che possiamo richiamare gli attributi ed attivare i metodi senza dover necessariamente istanziare ogni volta un oggetto specifico.
Vediamo un esempio:
<?php class Person { //attributi public $name; public $surname; public $age; //attributo statico public static $counter=0; //costruttore public function __construct($name, $surname, $age) { $this->name = $name; $this->surname = $surname; $this->age = $age; } //metodo public function presentati(){ echo "Ciao sono $this->name $this->surname ed ho $this->age anni! \n"; } } echo Person::$counter; //Output //0 ?>
Nell’esempio abbiamo creato un attributo statico caratterizzato dalla keyword “static”, seguita dalla dichiarazione della variabile a cui abbiamo assegnato un valore iniziale 0.
Abbiamo creato questo counter con l’obiettivo di contare quanti oggetti della classe Person saranno stati creati in un certo punto del nostro algoritmo.
Come notiamo, immediatamente, nel nostro codice, dove vogliamo far mostrare il valore della variabile attraverso il comando php echo, non abbiamo piú usato la sintassi $oggetto->attributo ma direttamente la classe Person seguita dallo SCOPE RESOLUTION OPERATOR(::) , un operatore che permette di accedere a dei metodi o proprietà statiche, costanti o sovrascritte di una classe.
Nel nostro caso, questo operatore attiverà la ricerca della classe Person e, al suo interno, andrà a cercare un attributo statico, con nome corrispondente a quello indicato, il nostro $counter.
Attenzione! Quando vogliamo catturare un attributo statico, dopo lo scope resolution operator dobbiamo, necessariamente, usare il $
Se facciamo partire il nostro programma, vedremo che ci darà come risultato 0, che é esattamente il valore di $counter.
Adesso proviamo a far incrementare questo contatore creando tanti oggetti della classe Person.
Essendo la funzione costruttore che “guida” l’istanziamento di un oggetto, è proprio al suo interno che dovremo gestire l’incremento di $counter.
<?php class Person { //attributi public $name; public $surname; public $age; //attributo statico public static $counter=0; //costruttore public function __construct($name, $surname, $age) { $this->name = $name; $this->surname = $surname; $this->age = $age; self::$counter++; } //metodo public function presentati(){ echo "Ciao sono $this->name $this->surname ed ho $this->age anni! \n"; } } $persona1 = new Person('Giuseppe','Verdi','56'); $persona2 = new Person('Paolo','Rossi','48'); $persona3 = new Person('Guglielmo','Bianchi','56'); echo Person::$counter; //Output //3 ?>
Nel costruttore abbiamo inserito l’incremento del contatore ma non utilizzando più la pseudo variabile “$this” seguita dalla “->” ma una nuova keyword “self”.
Se “$this” si riferisce all’oggetto che andremo a creare, la keyword “self” si riferisce, invece, esattamente alla classe: quindi, ogni qual volta viene richiamata la funzione costruttore (ad ogni new Person nel mio algoritmo), diremo alla classe di recuperare il suo stesso attributo statico $counter, aumentandolo di uno.
Se avviamo il programma, in output avremo come risultato 3 che, effettivamente, é il numero di oggetti Person creati nel nostro algoritmo.
E se volessimo creare una funzione che mostri il nostro contatore senza catturarlo direttamente dalla classe?
In quel caso, avremmo bisogno di un metodo statico:
<?php class Person { //attributi public $name; public $surname; public $age; //attributo statico public static $counter=0; //costruttore public function __construct($name, $surname, $age) { $this->name = $name; $this->surname = $surname; $this->age = $age; self::$counter++; } //metodo public function presentati(){ echo "Ciao, sono $this->name $this->surname ed ho $this->age anni.\n"; } //metodo statico public static function showCounter(){ echo self::$counter; } } $persona1 = new Person('Giuseppe','Verdi','56'); $persona2 = new Person('Paolo','Rossi','48'); $persona3 = new Person('Guglielmo','Bianchi','56'); Person::showCounter(); //Output //3 ?>
Se eseguiamo il nostro programma, vedremo lo stesso risultato dell’esempio precedente ma, questa volta, abbiamo utilizzato una metodologia di scrittura del codice piú elegante, che nasconde, tuttavia, un effettivo motivo: tra poco, infatti, affronteremo gli access modifiers o indicatori di accessibilità.
Gli access modifiers vanno a gestire la visibilità di determinati dati all’interno del nostro algoritmo: vedremo che taluni possono essere resi “privati” e, quindi, invisibili se non richiamati tramite un metodo, ma lo affronteremo nella prossima guida, in relazione all’ ereditarietà. Stay tuned!