Programmazione Java Avanzata Programmazione ObjectOriented in Java Ing. Gianluca Caminiti Testi di Riferimento (Java) Cay Horstmann Concetti di informatica e fondamenti di Java Apogeo, 2007 (Versione Inglese) Cay Horstmann Big Java 3rd edition Wiley, 2008 Sommario Richiami di base su Java Programmazione Object-Oriented (OOP) Incapsulamento, Ereditarietà, Polimorfismo Incapsulamento, Ereditarietà in Java Classi Astratte e Interfacce in Java Polimorfismo in Java 3 Richiami di base su Java In Java non esistono i puntatori, ma i riferimenti I riferimenti non si possono manipolare direttamente (come in C++) Creazione di riferimenti e instanziazione es. int i; (crea un riferimento ad int e lo istanzia) Object o; (crea un rif. ad Object ma non lo istanzia) Object o = new Object(); 4 Richiami di base su Java Convenzione: le variabili iniziano con lettera minuscola. Tutte le variabili (locali) devono essere inizializzate prima di essere utilizzate. Eccezione: I campi di esemplare sono inizializzati ad un valore di default. Parametro implicito (this). keyword final per dichiarare costanti. 5 Richiami di base su Java I tipi primitivi (numerici) come int, float, double, ecc. non sono “oggetti”. Per utilizzarli come tali esistono le classi “wrapper” Integer, ecc. Non esiste il concetto di puntatore, ma solo quello di riferimento. Tutte le variabili che contengono oggetti sono riferimenti, tranne quelle che contengono tipi primitivi. Non esiste il concetto di “distruttore” (per la presenza nella VM del Garbage Collector). 6 Richiami di base su Java Il passaggio di parametri è fissato: per valore (tipi primitivi) per riferimento (tipi oggetto) Le variabili locali devono essere inizializzate prima di essere utilizzate. Gli attributi, se non inizializzati dal costruttore, assumono il valore zero per i tipi numerici e null per quelli di tipo riferimento a oggetto. 7 Programmazione Object-Oriented Paradigma di programmazione che mette al centro la nozione di “oggetti”, raggruppati in “classi”. Una classe definisce un tipo di dati che rappresenta una nozione (concreta o astratta della realtà). Ogni oggetto è definito da un insieme di dati (attributi) e funzioni (metodi). Gli attributi ne rappresentano lo stato, i metodi ne modellano il comportamento. 8 Programmazione Object-Oriented Lo scopo principale dell’OOP è consentire il riuso del codice attraverso la sua modularizzazione per minimizzare la presenza di bug e accelerare i tempi di sviluppo del software. Caratteristiche fondamentali dei linguaggi OOP: Incapsulamento Ereditarietà Polimorfismo 9 Incapsulamento Ogni oggetto contiene sia i propri dati che le funzioni che operano su tali dati. L’accesso ai dati di un oggetto non può avvenire direttamente, ma soltanto attraverso i metodi pubblici di quell’oggetto. Questo risultato si ottiene usando i qualificatori di accesso. Oggetti come “scatole nere”: non sono noti i dettagli di funzionamento, ma solo l'interfaccia. E’ possibile cambiare l’implementazione di un oggetto senza influenzare gli oggetti che da esso dipendono. 10 Ereditarietà Estensione di una classe “base” attraverso il riuso del codice della stessa in una classe “derivata” che la specializza. La classe derivata “eredita” (li vede come se fossero i suoi) attributi e metodi (non privati) della classe base. Relazione IS_A (Principio di Sostituzione). La classe derivata può ridefinire attributi/metodi della classe base o avere attributi/metodi aggiuntivi. L’ereditarietà può essere singola o multipla. 11 Ereditarietà Mezzo di Trasporto Studente Lavoratore Automobile Studente-Lavoratore StationWagon 12 Polimorfismo Permette di avere metodi con la stessa signature che si comportano in modo differente a seconda degli oggetti su cui vengono invocati. Polimorfismo ed ereditarietà (subtyping): uso di metodi che accettano in input il super-tipo ma il cui comportamento si adatta ai sotto-tipi. Late binding – la scelta del metodo corretto avviene a run-time e non a compile-time (Virtual table o metadati). 13 Early/Late Binding Early Binding – Gli indirizzi dei metodi associati agli oggetti sono conosciuti a compile-time. E’ il compilatore a scegliere il metodo giusto fra i metodi candidati. Late binding – Gli indirizzi dei metodi associati agli oggetti non sono noti a compile-time. La selezione del metodo avviene a run-time (tramite Method Table o atre tecniche). Method Table – Ogni classe è associata ad una tabella che gestisce le chiamate dei metodi che è possibile invocare per quella classe. Ogni oggetto è associato alla tabella della classe corrispondente. 14 Incapsulamento in Java Qualificatori di accesso: public private protected (valido solo per attributi/metodi) package (per default) Per ciascun attributo/metodo si deve specificare un qualificatore (non esistono le “sezioni” del C++). 15 Ereditarietà in Java Sintassi: class Derivata extends Base Aggiunta/overriding di attributi/metodi Accesso ad attributi/metodi della classe Base: uso di super Ereditarietà “pubblica”: non è possibile ridurre l’accesso ad attributi/metodi nella classe Derivata attraverso overriding. Solamente ereditarietà singola. 16 Ereditarietà in Java Esempio: public class Studente extends Persona Studente può aggiungere attributi (es. matricola) o metodi (es. get_matricola()). Studente può (deve) ridefinire metodi di Persona (es. void print()). 17 Classi Astratte in Java Classi in cui alcuni metodi sono astratti (non sono implementati, c’è solo la signature). Sintassi: public abstract class FiguraGeometrica { public abstract double perimetro(); …} Non è possibile istanziare oggetti di una classe astratta. E’ possibile dichiarare riferimenti di tipo “astratto”. Per istanziare oggetti è necessario derivare una classe che implementa tutti i metodi astratti. 18 Classi Astratte in Java Esempio: public class Quadrato extends FiguraGeometrica { public double perimetro() { return misuraLato*4;} …} E’ possibile istanziare oggetti di Quadrato solo se tutti i metodi astratti ereditati sono implementati. E’ possibile inizializzare un riferimento FiguraGeometrica con un oggetto Quadrato (subtyping). 19 Interfacce in Java Simili alle classi astratte, ma possono contenere solo signature di metodi (pubblici) senza implementazione. Servono a “forzare” una classe a implementare un’insieme di metodi. I metodi sono pubblici per default. Sintassi: public interface FiguraGeometrica { public double perimetro(); …} Non è possibile istanziare oggetti di una interfaccia. E’ possibile dichiarare riferimenti di tipo “interfaccia”. 20 Interfacce in Java E’ possibile istanziare oggetti di una classe che implementa quell’interfaccia. Sintassi: public class Quadrato implements FiguraGeometrica { public double perimetro() { return misuraLato*4;} …} Le interfacce permettono di realizzare un meccanismo equivalente a quello dell’ereditarietà multipla (usando implements con più di una interfaccia alla volta). 21 Interfacce in Java E’ possibile: FiguraGeometrica f = new Quadrato(6); ? E’ possibile: Quadrato q = f;? 22 Interfacce in Java E’ possibile: FiguraGeometrica f = new Quadrato(6); ? SI E’ possibile: Quadrato q = f;? NO Quadrato q = (Quadrato) f; (si deve fare un casting possibilità di eccezioni) 23 Polimorfismo in Java Il comportamento del programma varia in funzione del tipo effettivo di un oggetto. Si può realizzare in tre modi: Usando le interfacce Usando le classi astratte Usando il subtyping 24 Polimorfismo (interfacce) Esempio: array di elementi di tipo FiguraGeometrica e calcolo del perimetro per ogni elemento. Ci sono due classi, Quadrato e Rettangolo, che implementano l’interfaccia FiguraGeometrica. Se x è di tipo FiguraGeometrica, che cosa restituisce x.perimetro()? 25 Polimorfismo (classi astratte) Esempio(idem): array di elementi di tipo FiguraGeometrica e calcolo del perimetro per ogni elemento. Ci sono due classi concrete, Quadrato e Rettangolo, che estendono la classe astratta FiguraGeometrica. Se x è di tipo FiguraGeometrica, che cosa restituisce x.perimetro()? 26 Polimorfismo (subtyping) Esempio: public class Studente extends class Persona … ho un array di oggetti di tipo Persona sui cui elementi invoco un metodo void print() Cosa succede se scrivo: Persona p = new Studente(“Mario”,“Rossi”, 46376); p.print(); ? 27 Fine I Parte Inizio II Parte Sommario Programmazione Generica Genericità con la classe Object Genericità con i template Gestione delle Eccezioni 30 Programmazione Generica Tecnica di programmazione per cui è possibile realizzare strutture dati e algoritmi che funzionano con diversi tipi di dati. In Java questo è possibile attraverso due tecniche: uso dell’ereditarietà uso delle classi generiche 31 Genericità con Object E’ un’estensione del principio di sostituzione applicata al fatto che ogni classe Java è sottoclasse (diretta o indiretta) della classe Object. Si creano strutture dati che utilizzano tipi Object per permettere l’inclusione di tipi generici. 32 Genericità con Object Vantaggi: compatibilità col codice legacy (prima di Java 1.5.0) Svantaggi: non c’è controllo sui tipi a tempo di compilazione si deve usare il casting per recuperare il behaviour dell’oggetto di partenza si deve leggere il codice per capire il tipo effettivo utilizzato 33 Genericità con Template Si usano dei “segnaposto” per rappresentare i tipi generici che sono usati nelle classi. Sintassi: public class nome_classe <T1, …> Vantaggi: Codice leggibile da chiunque Controllo a tempo di compilazione su violazioni di tipo Compatibilità col vecchio codice Svantaggi: nessuno, al momento. 34 Eccezioni controllate e non Eccezioni controllate: Il complatore controlla che noi non le ignoriamo dovute a circostanze esterne che il programmatore non può evitare Es. FileNotFoundException Eccezioni non controllate: rappresentano un errore del programmatore Es. ArrayIndexOutOfBoundsException Gestione delle Eccezioni Due Possibilità: 1. Catturare l’eccezione blocchi try / catch 2. Dire al compilatore che vogliamo terminare il metodo quando si verifica l’eccezione. Usare throws Enunciato finally Per eseguire task che devono essere comunque completati (sia in presenza che in assenza di errori, es. chiusura file) Eccezioni controllate e non Eccezioni controllate e non Riferimenti Cay Hortstmann, Concetti di Informatica e fondamenti di Java, Apogeo.