Introduzione
La programmazione orientata agli oggetti, OOP (Objects Oriented Programming), è ormai un paradigma che circola da molti anni, anche se la sua attuazione varia molto da linguaggio a linguaggio. C++, per esempio, è la versione di C orientata agli oggetti, e secondo alcuni puristi contiene più funzionalità OOP dello stesso Java. PHP, invece, ha un buon supporto per la programmazione ad oggetti solo a partire dalla versione 5.
La programmazione ad oggetti si basa sull'astrazione di modelli del mondo reale. Questo concetto, nuovo per la programmazione, non lo è, invece per la cultura occidentale. Già 2500 anni fa Platone aveva introdotto il concetto di essenzialismo, famosa la sua disputa con Antistene sul concetto di cavallinità che, secondo Platone, consente agli umani di riconoscere cavalli appartenenti a razze diverse grazie al modello astratto di cavallo che la nostra mente ha elaborato.
OOP è stata progettata per consentire ai programmatori di utilizzare modelli astratti con cui definire poi le realizzazioni concrete da usare nei programmi per computer. Lo scenario prevede la definizione di oggetti aventi delle proprietà e delle metodologie di azione.
Seguendo l'esempio di Platone, possiamo definire un oggetto di tipo Cane per un nostro progetto che si occupi di cani. Ci sono molti tipi di cani in tutto il mondo, ma possiamo fare un'astrazione su un modello base di Cane: quattro zampe, un naso bagnato, una avversione per gatti e scoiattoli, etc.
Così, a partire dal modello essenziale di cane, possiamo creare una razza barboncino, una razza Chihuahua, e una razza alsaziano. Ognuno di questi, a sua volta, è anche un modello, ma derivato dal progetto Cane. Dalla nostra razza barboncino possiamo quindi creare un barboncino, che chiameremo Fuffy. Fuffy è un cane vero, di razza barboncino, e quindi derivato dal progetto Cane. Con lo stesso meccanismo si possono creare altri cani veri di altre razze. La concretizzazione di un modello in una produzione vera prende il nome di istanza, pessima traduzione dell'inglese instance, ma ormai comunemente accetta in informatica, con tutte le sue declinazioni e coniugazioni: istanziazione, istanziare, etc.
Poichè tutti i cani abbaiano, possiamo aggiungere una funzione abbaia() al nostro progetto Cane, il che significa che anche la razza barboncino ha una funzione abbaia() e quindi Fuffy può abbaiare troppo perchè la sua funzione abbaia() supera certi limiti. Possiamo anche definire delle variabili all'interno del progetto Cane come $Name, $Age, e $Friendliness, e ancora una volta questo si ripercuoterà sulla razza barboncino, derivata dal progetto Cane, e quindi anche su Fuffy. Ogni oggetto di tipo barboncino avrà il proprio insieme di variabili: $Name, $Age, $Friedliness, etc.
Poiché le razze derivano dal progetto Cane, possiamo anche aggiungere funzioni e variabili a razze singolarmente senza che ci siano nel progetto Cane. Ad esempio, i barboncini sono disponibili in tre misure: standard, miniature, toy. Invece gli alsaziani sono solo di misura standard, quindi prevedere una variabile $Size nel progetto Cane potrebbe risultare inutilizzata in certe situazioni.
Classi
Questi progetti generali di razze di cani e di animali sono conosciuti come classi, e definiscono l'architettura di base degli oggetti disponibili nei nostri programmi. Ogni classe è definita come avente un insieme di funzioni e variabili, ed una nuova classe può ereditare le caratteristiche di un'altra classe. La classe Razza, per esempio, che discende dalla classe Cane, ne eredita tutte le funzioni e le variabili disponibili. Questo meccanismo è spesso definito sub-classing, quindi il Barboncino sarebbe una sotto-classe di Cane.
Alcuni linguaggi, come il C++, consentono di ereditare da più di una classe, il che è conosciuto come ereditarietà multipla. Questa tecnica permette, avendo una classe Uccello ed una classe Cavallo, di creare una nuova classe denominata CavalliVolanti che eredita entrambe le caratteristiche degli uccelli e dei cavalli, e fornisce il supporto per il mitico cavallo volante Pegaso. PHP non consente di fare questo perché produrrebbe generalmente dei programmi molto confusi, ma anche in C++ questa tecnica, se pur possibile, non è molto usata.
PHP permette di ereditare da una classe genitore, e questo meccanismo può essere ripetuto tutte le volte che sia necessario. Ad esempio, la classe Cane potrebbe ereditare dalla classe Carnivori (che conterrebbe gatti, cani, orsi, etc), la classe Carnivori potrebbe ereditare dalla classe Mammiferi, che potrebbe a sua volta ereditare dalla classe Vertebrati, e così via man mano risalendo con caratteristiche sempre più vaghe. Questo perché ogni classe eredita le funzioni e le variabili dalla classe precedente, ma ne aggiunge di proprie.
La struttura finale nel contesto assomiglierà molto a quella di un albero genealogico: nonno, padre, figlio, nipote, ...
Adesso basta con le generalizzazioni, andiamo nello specifico. Vediamo come la struttura delle classi cani e razze di cui abbiamo parlato si possa tradurre in codice PHP. Ecco il codice necessario per definire una classe Cane molto semplice:
class cane {
public function abbaia() {
print "Bau!\n";
}
}
In questo caso la classe cane contiene al suo interno una sola funzione, abbaia(), definita public perchè può essere chiamata da chiunque, e restituisce semplicemente Bau! Molto semplice, come si vede. Adesso nel momento in cui creiamo un oggetto di classe cane possiamo invocare la funzione abbaia() per avere in output il messaggio Bau!
Un uomo di genio non può fare a meno di nascere dove nasce.
Ezra W.L. Pound (1885-1972)