
Benvenuto! Se sei un nuovo visitatore ti consiglio di iscriverti al mio Feed RSS in modo da essere sempre aggiornato riguardo l'uscita di nuovi articoli oppure sbirciare tra i tutorials ed i progetti.
Per avere un'idea del best-content presente in questo blog puoi leggere il post intitolato "Ed ora è il momento di rilanciare alcune iniziative! (1a parte e 2a parte)".
Buona navigazione e grazie per la visita!
Introduzione
In questi ultimi anni, chi si è appena affacciato al mondo della programmazione, avrà sentito parlare di "programmazione orientata agli oggetti"; con questo termine si intende un modo di programmare che gira attorno al concetto di oggetto, ma cos'è un oggetto?
Un oggetto (object) è un entità che ha un contenuto e alla quale si possono inoltrare delle richieste specifiche al fine di eseguire delle operazioni su di esso.
Un oggetto per dirla in altri termini ha uno stato(dato dall'insieme delle variabili e in generale dal suo contenuto), un comportamento (costituito dai metodi) e un'identità (l'handle ossia quell'indirizzo di memoria univoco per riferirsi all'oggetto in questione).
Noi possiamo immaginare una lampadina come un oggetto che avrà delle proprietà particolari (potenza, colore, ecc...) e delle azioni specifiche (accensione, spegnimento).
Ogni oggetto però non sarà visibile nella sua interezza dagli utilizzatori perchè avrà su di se un'interfaccia che ne faciliterà l'interazione; si può considerare l'interruttore di accensione e spegnimento come un interfaccia che nasconde a noi il vero funzionamento di una lampadina (quindi quanta corrente andrà fatta passare, come funziona internamente, ecc...); tutto ciò permette quindi alla lampadina di essere utilizzata da tutti (sia da chi ha creato la lampadina e sia da chi ignora il suo funzionamento interno).
Dopo aver detto ciò si può capire l'importanza di nascondere l'implementazione perchè l'utilizzatore non si preoccuperà di come è fatta al suo interno la lampadina, ma dovrà solo sapere pochi aspetti relativi all'utilizzo dell'interruttore.
Dopo questa breve panoramica generale, studiamo i vari aspetti della programmazione orientata agli oggetti utilizzando come linguaggio didattico Java.
Classe Lampadina
Incapsulamento
L'incapsulamento sarà ottenuto quando le proprietà dell'oggetto saranno modificabili mediante i metodi che lo stesso oggetto mette a disposizione all'utente (mediante la relativa interfaccia).
La lampadina incapsula a se i fili, resistenze, ecc... e esternalizza solo l'interruttore che permette di agire indirettamente su questi componenti elettrici (e quindi per spegnere la lampadina non dovrò agire sui fili ma sull'interruttore).
Quindi una lampadina con fili scoperti facilmente manomettibili, resistenze variabili esterne, ecc... non soddisferà il principio di incapsulamento perchè chiunque potrà toccare con mano questi componenti (rischiando la fulminazione ;) e bypassare quindi l'utilizzo dell'interruttore.
Nella nostra classe di esempio per accendere la lampadina non agisco direttamente sulla variabile "acceso" ma mediante i metodi accendi() e spegni(), come in questo esempio:
Occultamento dell'informazione (information hiding)
Questo tipo di occultamento si ottiene rendendo non visibile la struttura interna dell'incapsulamento; quindi riprendendo la metafora con la lampadina non dovremmo far vedere all'utente resistenze, relè che servono solo al funzionamento interno della lampadina e che quindi all'utente non devono interessare.
Questa particolarità della programmazione orientata agli oggetti si ottiene mediante il corretto utilizzo di 3 parole chiave quali:
Java inoltre ha un'altra tipologia d'accesso di default che rende l'elemento d'interesse visibile solo a classi appartenenti allo stesso package e viene per questo chiamato package access.
Occultamento dell'implementazione (implementation hiding)
Con questo concetto si vuole tenere nascosto all'utente il vero funzionamento della lampadina.
Nella nostra classe d'esempio si può vedere come l'utente non potrà sapere (ma solo immaginare) che lo stato della lampadina corrisponde ad una variabile booleana (poteva benissimo essere di tipo int oppure una stringa), visto che l'utente accende e spegne la lampadina solo richiamando i metodi corrispondenti.
Conservazione dello stato
La conservazione dello stato è una proprietà fondamentale perchè fa in modo che quando noi stacchiamo l'interruttore dalla lampadina questa rimanga accesa (o spenta).
Lo stato dell'oggetto, costituito da tutti i suoi valori, rimarrà tale durante tutta la vita dello stesso ma verrà perduto quando verrà distrutto l'oggetto.
Identità degli oggetti
L'identità di un oggetto costituisce il suo riferimento e non è altro che un indirizzo di memoria univoco che risiede nello heap (handle).
Potrebbero formarsi delle situazioni pericolose in cui un oggetto rimanga senza alcun riferimento ma nel caso specifico di Java (e di altri linguaggi) la presenza del Garbage Collector ripulisce la memoria di tutti gli oggetti non utilizzati (senza riferimento).
Nell'esempio vediamo come vada perso il riferimento al secondo oggetto (che quindi non sarà più accessibile e verrà quindi spazzato via).
Concetto di classe e di oggetto
La classe è un modello per entità che hanno in comune determinati aspetti (variabili e metodi), mentre l'oggetto è l'entità generabile da una determinata classe.
Per mettere a fuoco meglio i due concetti possiamo immaginare la categoria dei lavoratori (quindi abbiamo una classe Lavoratore) e ciascun lavoratore che svolge una determinata mansione (ossia oggetti creati dalla stessa classe).
Potremo avere attributi e metodi di due tipi:
Principalmente le due tipologie si contraddistinguono dal fatto di avere come keyword Static che rende un metodo o una variabile di classe (altrimenti è d'oggetto).
Nel nostro caso abbiamo un metodo statico utile per sapere il numero totale di lampadina istanziate:
Come potete notare si può richiamare un metodo statico facendo riferimento sia alla classe che all'oggetto (la stessa cosa non vale ovviamente per i metodi o variabili d'istanza).
Una precisazione da fare (giusto per confondere ulteriormente le idee :P), le stesse classi sono oggetti della classe Class e ogni classe eredita dalla classe Object.
Ereditarietà e Composizione
Il vantaggio più evidente nell'addottare questi accorgimenti riguarda la possibilità di riutilizzo delle classi portando quindi ad un risparmio di tempo notevole (sia per quel che riguarda la velocità di aggiornamento).
Creare una lampadina lampeggiante da una lampadina normale risulta più facile che crearla dall'inizio.
Ecco il codice di una pseudo-lampadina lampeggiante:
L'ereditarietà permette di utilizzare, così come sono, metodi e variabili (se non private) delle sovraclassi (in questo caso della sovraclasse Lampadina).
I metodi ereditati nel nostro caso sono:
Quando estendiamo una classe abbiamo la possibilità di sovrascrivere determinate metodi, come abbiamo fatto nel metodo toString() che richiama il metodo omonimo della sovraclasse per poi aggiungerci l'informazione riguardante la frequenza (ottenendo quindi due comportamenti diversi per ciascuna delle classi).
Oltre a poter ereditare e sovrascrivere metodi possiamo aggiungerne di nuovi e quindi di fatto estendere la sovraclasse.
I metodi aggiunti sono:
La lampadina lampeggiante quindi avrà il "parametro frequenza" aggiunto, il metodo toString() sovrascritto (in modo da includere l'informazione relativa alla frequenza) e tutti gli altri metodi ereditati da una normale lampadina (quali potenza e colore).
Oltre all'ereditarietà appena descritta esiste anche la composizione, nella quale all'interno di una particolare classe si creando ed utilizzano altri oggetti.
Per spiegare meglio il concetto possiamo pensare il volto di un umano come una classe, nella quale al suo interno ci saranno oggetti istanziati dalle classi Occhio, Bocca, Naso, ecc... si può quindi notare che non vi è alcuna ereditarietà (un occhio non ha niente in comune con il volto, ecc...) ma solo un utilizzo di oggetti distinti all'interno di una o più classi.
Comunemente entrambi i metodi vengono utilizzati insieme, con la differenza che la composizione viene usata quando si vogliono utilizzare i metodi e le proprietà di una classe all'interno di un'altra senza la sua interfaccia (settando eventualmente come private gli oggetti istanziati all'interno della classe).
Polimorfismo
Il polimorfismo consiste nel cambio di comportamento di uno stesso metodo a seconda dell'oggetto a cui ci si riferisce (detta in parole povere), e questo risulta essere possibile principalmente grazie al late binding.
Il late binding è una proprietà di Java (e di altri linguaggi) che permette di conoscere il tipo di un oggetto in tempo di esecuzione, richiamando il metodo adeguato.
Ecco un esempio:
Possiamo vedere che il legame tra l'identificatore "illuminazione" e i vari oggetti ("a" e "b") è stabilito in tempo di esecuzione e non di compilazione, chiamando il metodo toString() adeguato.
Possiamo notare che una forma similare di "adattamento" (che non ha niente a che fare con il polimorfismo) coinvolge anche il costruttore (e in generale tutti i metodi) che è presente più volte all'interno della classe ma sempre con segnatura (che contraddistingue numero e ordine dei parametri) diversa.
Quando creeremo un oggetto, a seconda dei parametri passati, verrà richiamato il costruttore opportuno.
Conclusione
In questo tutorial ho voluto dare una panoramica generale della programmazione orientata agli oggetti quindi alcuni aspetti sono stati volutamente ignorati o comunque non approfonditi, tutto ciò per essere il più possibile indipendente dal linguaggio di programmazione utilizzato (ad esempio non ho parlato delle classi astratte, interfacce e delle classi parametriche).
Ovviamente linguaggi di programmazione diversi differiscono per alcuni aspetti, ad esempio Actionscript 2 non prevede l'overloading (sovraccarico) del costruttore, ecc...
Insomma questo tutorial da solo un'introduzione all'argomento che potete approfondire grazie al nostro amico Google ;)
Daniele Simonin 22 Dicembre 2005 alle 13:34 Trackback URI
| L | M | M | G | V | S | D |
|---|---|---|---|---|---|---|
| « Apr | ||||||
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 | |
Scrivi un commento
Tags di formattazione:
Leggi l'unico commento presente fin'ora
yeah! grande snakko
Commento di pigiuz 20 Novembre 2006 alle 17:03