Mio nonno mi diceva che…
Object-oriented programming (da ora OOP) è il paradigma di programmazione dominante al giorno d’oggi e ha rimpiazzato in molti ambiti le tecniche di programmazione più datate, ovvero quelle cosiddette procedurali. Nasce in risposta alla “crisi” del software avutasi tra la fine degli anni ’60 e l’inizio degli anni ’70; in quegli anni di Hippies e Juke Box il software era diventato sempre più complesso, ma allo stesso tempo più instabile e la manutenzione era un costoso incubo da cui il business desiderava svegliarsi; siccome di solito l’umanità dopo che il problema si presenta pensa ad una soluzione si è introdotto un nuovo radicale approccio alla programmazione che consentisse la scalabilità e la modularità richieste.
La risposta è stata l’object oriented; il concetto è semplice: se riesco a individuare moduli riusabili che posso sviluppare una volta ma riutilizzare n volte la produttività e l’affidabilità aumentano. Questo principio è stato applicato in molti ambiti: si pensi all’edilizia (case prefabbricate), all’industria automobilistica (assemblaggio in catene di montaggio a partire da moduli integrabili) e così via. L’industria del software, più giovane e ad alto contenuto di progettazione, si è adeguata più tardi a questo tipo di mentalità, ma l’introduzione dell’object oriented ha consentito al software di crescere nuovamente senza far lievitare i costi o diminuire l’affidabilità.
Lasciate ogni speranza voi ch’entrate
Si dice spesso che il paradigma Object Oriented è molto ostico per chi lo approccia provenendo dal mondo procedurale. Io penso però che tutto ciò che è richiesto è una mentalità aperta e il provare ad approcciare i problemi in un modo nuovo. Con queste accortezze in mente, vedrete: sarà una passeggiata!
Parla come mangi
Addentriamoci nel mondo dell’OOP: una terminologia corretta sarà il Virgilio che ci guiderà fino alla cima del monte Purgatorio.
Classi e oggetti
Il termine più importante è classe: è in sostanza un template, un tipo in base al quale andremo a costruire oggetti: ogni oggetto avrà una classe, ovvero un tipo che lo caratterizza. Volete pensare alle formine per fare i biscotti? Con quella a stella faccio tanti biscotti a stella…mamma mia che orrore!
Incapsulamento/data hiding
L’incapsulamento o data hiding è un concetto chiave quando si manipolano oggetti. In due parole: in ogni classe vengono incapsulati dati (proprietà) e comportamento (metodi) e si nasconde l’implementazione interna dell’oggetto all’utilizzatore dell’oggetto stesso. Questo consente:
- all’utilizzatore di non dovere necessariamente sapere cosa consente alla classe che utilizza di fornire certi servizi (chi utilizza l’automobile può non sapere e di fatto spesso non sa cosa c’è dentro il cofano, è un semplice utilizzatore)
- a chi progetta la classe (la libreria, il framework) la libertà di modificare l’implementazione per migliorarla o adeguarla a mutate condizioni senza impattare tutti gli utilizzatori della classe stessa
Ogni oggetto deve sostanzialmente essere una cosiddetta black box, questa è la chiave per il riutilizzo e l’affidabilità: il modo in cui lo stato interno di una classe viene salvato può cambiare completamente, ma chi la utilizza, tramite gli appositi metodi di servizio della classe, non se ne dovrà accorgere.
E in principio era Object
All’inizio dei tempi era Object: poi è esploso… nei primi 30 secondi si sono create milioni di classi che lo estendevano…la JDK era nata! E qua aggiungiamo un altro concetto basilare: le classi possono essere costruite estendendo altre classi. Object è una classe “cosmica”: tutte le altre la estendono. Quando si estende una classe esistente la nuova classe ha tutte le proprietà e i metodi della classe originaria, in più può possedere proprietà e metodi specifici. Stiamo parlando dell’ereditarietà, ricordate? L’abbiamo vista insieme nel nostro post sulla modellizzazione UML.
Oggetti
Lavorare con gli oggetti significa in sostanza identificarne tre caratteristiche chiave:
- Comportamento
- – cosa posso fare con questo oggetto, quali metodi posso invocarne
- Stato
- – come reagisce un oggetto quando invochi i suoi metodi
- Identità
- – come distinguo un oggetto dagli altri che possano avere lo stesso comportamento e stato (la “chiave primaria” per voi DB Guys)
Tutti gli oggetti istanza di una stessa classe condividono in realtà lo stesso comportamento. Ogni oggetto però possiede uno stato che può cambiare nel tempo in seguito alla chiamata di uno o più dei suoi metodi. Tuttavia lo stato non identifica completamente un oggetto: per esempio potrei avere due ordini distinti che contengono però gli stessi articoli, in quantità e qualità.
Quale tasto premo quindi?
Per sfortuna non è così semplice: tuttavia qualche consiglio si può dare a chi proviene dal mondo procedurale e comincia ad utilizzare un linguaggio OOP; di solito in un programma procedurale tradizionale si comincia dall’algoritmo, con un approccio top-down, e si procede a scrivere il main. Quando si progetta un sistema object-oriented non esiste un top da cui iniziare, ma bisogna invece indentificare le classi in gioco, aggiungere loro metodi e proprietà e poi farle interagire, in modo che assieme, ciascuna per le proprie competenze, realizzino quanto atteso.
Quando siete riusciti a fare un diagramma UML di classi del vostro sistema avete già individuato questi aspetti!
Utilizzare le classi predefinite di Java
Prima di vedere come scrivere le nostri classi vediamo come usarne qualcuna che esiste già. Java è una piattaforma che si compone di tre aspetti:
- Linguaggio
- Java Virtual Machine (avremo modo di parlarne)
- API (Application programming interface)
Le API, o librerie, contengono già tantissime classi pronte per noi, che possiamo usare senza sforzo.
La classe Date
Cominciamo a divertirci con le date! In Java esiste java.utils.Date. Come si costruisce una istanza di tipo java.utils.Date? Così:
new Date() |
L’operatore new è seguito da un metodo speciale, chiamato costruttore. Dopo l’istruzione precedente abbiamo in memoria una istanza di java.utils.Date valorizzata con la data corrente. Di solito però dopo aver creato un oggetto vorremmo poterlo usare subito dopo. Per questo motivo in genere si salva il riferimento all’oggetto creato dall’operatore new in una variabile:
Date oggi = new Date(); |

E’ interessante la distinzione tra variabile e oggetto: oggi è un oggetto, infatti punta ad un oggetto caricato in memoria. La seguente linea di codice invece:
Date domani; |
dichiara una variable che non è un oggetto, in quanto non è stata inizializzata e non punta quindi a nessuna locazione di memoria: il suo valore è null. Una variabile, prima di essere utilizzata, deve essere inizializzata: questo può anche essere fatto con il valore di un oggetto già esistente:
domani = oggi; |
In seguito alla precedente istruzione abbiamo la seguente situazione:

L’istruzione Java:
Date domani = new Date(); |
corrisponde all’istruzione C++ seguente:
Date* domani = new Date();
Conclusioni
Pronti a scrivere la nostra prima classe Java? Bene, così nel prossimo post la scriviamo! :-).
Alla prossima!