Relazione conclusiva
Di: Stefano Morini
L’aspetto principale del corso è stato quello di presentare un nuovo approccio (OOP) alla
progettazione e allo sviluppo delle applicazioni.
Il concetto nuovo alla base dell’ Object Oriented Programming, come si evince già dal
nome, è quello di Oggetto come entità auto sufficiente, che fornisce servizi al mondo
esterno nascondendo la gestione interna. In questo modo risulta possibili separare il
comportamento offerto ai clienti che usano l’oggetto, tramite la sua interfaccia, da come
vengono implementate all’interno dell’oggetto i metodi usati dai vari clienti, ciò porta alla
protezione dei dati “campi” che non sono accessibili direttamente ma attraverso dei metodi
messi a disposizione dall’oggetto, è quindi l’oggetto stesso a regolarne l’accesso.
Tuttavia come ho notato nella prima esercitazione la protezione non è totale, in quanto tra
istanze dello stesso oggetto e possibile accedere direttamente al campo bypassando i
metodi.
Di un oggetto se ne possono avere più copie, tutte create (istanziate ) a partire da un tipo
di dato astratto ADT.
Un ADT è un astrazione che cerca di dare una rappresentazione di un entità reale
definendone le proprietà e le caratteristiche degli oggetti che varranno creati da esse,
funge come uno stampino.
Gli oggetti diventano delle entità reattive che interagiscono fra di loro attraverso lo
scambio di messaggi, e che si adattano alle varie condizioni d’uso ; ad esempio nel
progetto finale l’oggetto SubNet si adatta (mediante un’impostazione dell’utente, ma
sarebbe in grado di farlo da solo durante la creazione) alla rete su cui si trova ed
interagisce con gli altri oggetti ricevendo e spedendo messaggi.
Utilizzando gli oggetti e così possibile sviluppare applicazioni ben organizzate che
simulano la realtà, protetto (o almeno si cerca di farlo), modulare (ogni oggetto è a se
stante), riconfigurabile (può essere cambiata l’implementazione interna senza che gli
utilizzatori notino i cambiamenti), flessibile (è in grado di adattarsi alle situazioni) ed
estendibile (tramite l’ereditarietà è possibile estendere le funzioni mantenendo la
compatibilità).
Java è un linguaggio “totalmente” ad oggetti, anche se lascia la libertà allo sviluppatore di
decidere se definire, per i tipi primitivi, delle variabili o degli oggetti; cioè decidere, ad
esempio per gli interi, se usare il tipo primitivo “int” o la classe “Integer”. Anche scegliendo
il tipo “int” java, per svolgere alcune funzioni come l’output, fa il casting alla classe
corrispondente per poi applicargli il metodo (toString()) che permette di poterlo scrivere su
output.
Per sfruttare le potenzialità degli oggetti java ha introdotto il concetto di classe che ha un
duplice utilizzo: come componente software statico avente propri dati e metodi, ma da cui
non è possibile istanziare oggetti, e come definizione di un tipo di dato astratto da cui
dinamicamente è possibile istanziare oggetti.
In java, come nella OOP, è possibile incapsulare oggetti in altri conferendo a questi ultimi
la possibilità di delegate agli altri messaggi che non sono in grado di gestire; in questo
caso si dice che un oggettoA ha un oggettoB al suo interno, questo è stato studiato
nell’esercitazione 2 in cui l’Orario aveva tre Counter al suo interno, e a cui diceva di
incrementarsi quando gli arrivava un messaggio determinato.
(Vorrei correggere un errore fatto nella parte di analisi della relazione 2. Quando dico :
“L’Adt Orario realizzato è un oggetto composto che ha un contatore” lo vorrei correggere
con “L’Orario realizzato è un oggetto composto che ha un contatore” . Un ADT non è un
oggetto ma uno stampo per oggetti. Grazie)
La capacità di ereditare da una classe campi e metodi è un’altra caratteristica della OOP
molto importante, che oltre a rendere riusabile il codice da la possibilità di creare oggetti
che si comportano come il precedente ma hanno anche qualcosa in più, in questo caso un
oggettoA è anche un oggettoB. In java esiste l’ereditarietà singola a livello di classe, per
evitare problemi dovuti omonimie di metodi e/o campi, e multipla a livello di interfacce.
Altro concetto studiato nella esercitazione 3 è quello di polimorfismo, con cui si stabilisce
che un riferimento o un metodo devono adattarsi allo specifico oggetto su cui devono
operare, per quest’ultimo punto java è un linguaggio che supporta totalmente il
polimorfismo.
Le classi astratte e le interfacce sono una parte molto importante perché permettono,
soprattutto le ultime, di svincolare completamente l’implementazione dal comportamento
esterno osservabile. Le classi astratte definiscono solo i metodi comuni di una determinata
entità generale (ex: animale) gli altri vengono solamente dichiarati, lasciando alle classi
che la erediteranno (ex: cavallo), specializzandola, il compito di implementarli. Le
interfacce invece contengono solo le dichiarazione dei metodi che una classe che la
implementerà dovrà definire. Le interfacce rappresentano solamente la vista esterna che
può essere totalmente slegata dalle scelte implemetative interne, come risulta
dall’esempio Complex-Real analizzato a lezione.
L’altro aspetto importante del corso è stato quello di spostarsi da una programmazione
lineare e senza alcun intervento dell’utente a runtime, ad una programmazione eventdriven in cui è proprio l’utente stesso a comandare, attraverso la generazione di eventi (ex:
pressione di bottoni), azioni all’applicazione.
Considerando tutto il lavoro svolto nelle esercitazioni, compresa la parte facoltativa, e
l’impegno messo nella realizzazione del progetto finale, credo di meritare un 30.
Stefano Morini
P.S. Credo e spero di aver presentato un quadro generale del corso.