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.