IL TEMA DELLA RIUSABILITÀ Si vuole riusare tutto ciò che può essere riusato (componenti, codice, astrazioni) Non è utile né opportuno modificare codice.

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

© 2007 SEI-Società Editrice Internazionale, Apogeo Unit à B2 Gli oggetti: concetti avanzati.
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità B1 Le basi della programmazione a oggetti.
Oggetti Java.
Recupero debito quarto anno Primo incontro
Recupero debito quarto anno Secondo incontro
Informatica Recupero debito quarto anno Terzo incontro.
Differenze nei vari linguaggi di Elisa Trifirò e Barbara Tacchino
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
LIP: 4 Aprile 2008 ECCEZIONI. Eccezioni Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
Le gerarchie di tipi.
LIP: 19 Aprile Contenuto Soluzione Compitino Tipo di dato MultiSet, estensione con sottoclasse.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
SISSIS MODULO DI JAVA PER LA CLASSE IV DELL’ITI
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
1 Lezione XIII Lu 17-Nov-2005 Programmare le classi.
Derivazione tra classi
Overriding.
Gerarchia di classi Java
Approfondimento delle classi
1 Le gerarchie di tipi. 2 Supertipi e sottotipi 4 un supertipo –class –interface 4 può avere più sottotipi –un sottotipo extends il supertipo ( class.
Lab. Calc. 2005/06 Ereditarietà. Lab. Calc. 2005/06 Scopo di questa lezione: Imparare a creare nuove classi ereditando da classi già esistenti. Capire.
Java base IV: Java e la programmazione O.O.
LA DOCUMENTAZIONE È noto che un buon programma dovrebbe essere ben documentato.. ma lesperienza insegna che quasi mai ciò viene fatto! –non cè tempo, ci.
CLASSI ASTRATTE L’ereditarietà porta riflettere sul
IL CONCETTO DI PACKAGE Una applicazione è spesso composta di molte classi (eventualmente correlate) Un package è un gruppo di classi che costi- tuiscono.
CLASSI ED EREDITARIETÀ Come si è visto, è cruciale che la gerarchia rispecchi la realtà del mondo ma a volte ciò contraddice principi di efficienza Esempio:
OGGETTI COMPOSTI Una classe può contenere riferimenti a altre classi (o anche a se stessa): public class Orologio { Counter ore, minuti; } Loggetto Orologio.
IL TEMA DELLA RIUSABILITÀ Si vuole riusare tutto ciò che può essere riusato (componenti, codice, astrazioni) Non è utile né opportuno modificare codice.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Programmazione in Java (8)
AlgoLab - Ereditarieta' Ereditarietà e polimorfismo in Java Laboratorio di Algoritmi 02/03 Prof. Ugo de Liguoro.
Ereditarietà e Polimorfismo
Introduzione alla programmazione Object Oriented
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA INTERMEDIA DEL 12 MARZO 2007 NOME: COGNOME: ________________________________________________________________________________.
Enumerazioni e Classi 1. Enumerazioni Permettono di definire nuovi tipi che consistono in un insieme di valori costanti (ognuno con un nome) – Migliorano.
1 Lucidi delle esercitazioni di Sistemi di Elaborazione in Rete Università degli Studi della Calabria Corso di Laurea in Ingegneria Gestionale A.A. 2003/2004.
Fondamenti di Programmazione Prof.ssa Elisa Tiezzi
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA FINALE DEL 21 MAGGIO 2007 NOME: COGNOME: ________________________________________________________________________________.
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA INTERMEDIA DEL 12 MARZO 2007 NOME: COGNOME: ________________________________________________________________________________.
I nomi in Java F. Bombi 18 novembre novembre 2003.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Fondamenti di Informatica II Ingegneria Informatica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
1 Eccezioni in Java. 2 Ricordiamo che 4 una procedura può terminare –normalmente, ritornando un risultato –in modo eccezionale ci possono essere diverse.
Gestione dei thread in Java
Fondamenti di informatica Oggetti e Java Luca Cabibbo Luca Cabibbo – Fondamenti di informatica: Oggetti e Java Copyright © 2004 – The McGraw-Hill Companies.
Programmazione in Java. Classi I programmi in Java consistono di classi. Le classi consentono di definire: collezioni di procedure (metodi statici) tipi.
1 Semantica Operazionale di un frammento di Java: le regole di transizione estensione (con piccole varianti) di quella in Barbuti, Mancarella, Turini,
Esercitazione del 7 marzo 2008 Ereditarieta’. Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro.
Cose nuove di Java (prima a chiacchiera, poi formalmente)
LIP: 2 Maggio 2008 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
LIP: 11 Maggio 2007 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
LIP: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
Fondamenti di informatica T-A Esercitazione 3 : Classi, metodi, visibilità, metodi statici AA 2012/2013 Tutor : Domenico Di Carlo.
Corso di Algoritmi e Strutture Dati con Laboratorio Richiami di Java – parte II.
La programmazione ad oggetti
28/12/2001package 1 Package Pacchetti e interfacce.
Introduzione all’Ereditarietà Pietro Palladino. Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce.
Introduzione alle Classi e agli Oggetti in Java 1.
Transcript della presentazione:

IL TEMA DELLA RIUSABILITÀ Si vuole riusare tutto ciò che può essere riusato (componenti, codice, astrazioni) Non è utile né opportuno modificare codice già funzionante e corretto il cui sviluppo ha richiesto tempo (anni-uomo) ed è costato (molto) denaro Occorre disporre nel linguaggio di un modo per progettare alle differenze, procedendo incrementalmente.

LOBIETTIVO Poter definire una nuova classe a partire da una già esistente Bisognerà dire: –quali dati la nuova classe ha in più rispetto alla precedente –quali metodi la nuova classe ha in più rispetto alla precedente –quali metodi la nuova classe modifica rispetto alla precedente.

EREDITARIETÀ Una relazione tra classi: si dice che la nuova classe B eredita da la pre-esistente classe A B A eredita_da classe base (superclasse) classe derivata (sottoclasse)

EREDITARIETÀ La nuova classe ESTENDE una classe già esistente –può aggiungere nuovi dati o metodi –può accedere ai dati ereditati purché il livello di protezione lo consenta –non può eliminare dati o metodi !! La classe derivata condivide la struttura e il comportamento (per le parti non ridefinite) della classe base

ESEMPIO Dal contatore (solo in avanti) … public class Counter { private int val; public Counter() { val = 1; } public Counter(int v) { val = v; } public void reset() { val = 0; } public void inc() { val++; } public int getValue() { return val;} } Attenzione al- la protezione!

ESEMPIO … al contatore avanti/indietro (con decremento) public class Counter2 extends Counter { public void dec() { val--; } } Questa nuova classe: eredita da Counter il campo val (un int ) eredita da Counter tutti i metodi aggiunge a Counter il metodo dec()

ESEMPIO … al contatore avanti/indietro (con decremento) public class Counter2 extends Counter { public void dec() { val--; } } Questa nuova classe: eredita da Counter il campo val (un int ) eredita da Counter tutti i metodi aggiunge a Counter il metodo dec() Ma val era privato!! ERRORE: nessuno può accedere a dati e metodi privati di qualcun altro!!!

EREDITARIETÀ E PROTEZIONE Problema: il livello di protezione private impedisce a chiunque di accedere al dato, anche a una classe derivata –va bene per dati veramente privati –ma è troppo restrittivo nella maggioranza dei casi Per sfruttare appieno lereditarietà occorre rilassare un po il livello di protezione –senza dover tornare però a public –senza dover scegliere per forza la protezione package di default: il concetto di package non centra niente con lereditarietà!

LA QUALIFICA protected Un dato o un metodo protected è come package (il default) per chiunque non sia una classe derivata ma consente libero accesso a una classe derivata, indipendentemente dal package in cui essa è definita. Occorre dunque cambiare la protezione del campo val nella classe Counter

ESEMPIO Il contatore riadattato... public class Counter { protected int val; public Counter() { val = 1; } public Counter(int v) { val = v; } public void reset() { val = 0; } public void inc() { val++; } public int getValue() { return val;} } Nuovo tipo di protezione!

ESEMPIO … e il contatore con decremento: public class Counter2 extends Counter { public void dec() { val--; } } Ora funziona !

UNA RIFLESSIONE La qualifica protected : rende accessibile un campo a tutte le sottoclassi, presenti e future costituisce perciò un permesso di accesso indiscriminato, valido per ogni possibile sottoclasse che possa in futuro essere definita, senza possibilità di distinzione.

EREDITARIETÀ Cosa si eredita? tutti i dati della classe base –anche quelli privati, a cui comunque la classe derivata non potrà accedere direttamente tutti i metodi... –anche quelli che la classe derivata non potrà usare direttamente... tranne i costruttori, perché sono specifici di quella particolare classe.

EREDITARIETÀ E COSTRUTTORI Una classe derivata non può prescindere dalla classe base, perché ogni istanza della classe derivata comprende in sé, indiretta- mente, un oggetto della classe base. Quindi, ogni costruttore della classe derivata deve invocare un costruttore della classe base affinché esso costruisca la parte di oggetto relativa alla classe base stessa: ognuno deve costruire quello che gli compete

EREDITARIETÀ E COSTRUTTORI Perché bisogna che ogni costruttore della classe derivata invochi un costruttore della classe base? –solo il costruttore della classe base può sapere come inizializzare i dati ereditati in modo corretto –solo il costruttore della classe base può garantire linizializzazione dei dati privati, a cui la classe derivata non potrebbe accedere direttamente –è inutile duplicare nella sottoclasse tutto il codice necessario per inizializzare i dati ereditati, che è già stato scritto.

EREDITARIETÀ E COSTRUTTORI Ma come può un costruttore della classe derivata invocare un costruttore della classe base? I costruttori non si possono mai chiamare direttamente! Occorre un modo per dire al costruttore della classe derivata di appoggiarsi a un opportuno costruttore della classe base: per questo si usa la parola chiave super

ESEMPIO Il contatore con decremento: public class Counter2 extends Counter { public void dec() { val--; } public Counter2() { super(); } public Counter2(int v) { super(v); } } Lespressione super(... ) invoca il costrut-tore della classe base che corrisponde co-me numero e tipo di parametri alla lista data. Costruttore di default generato automaticamen-te dal sistema in assenza di altri costruttori

EREDITARIETÀ E COSTRUTTORI E se non indichiamo alcuna chiamata a super(... ) ? Il sistema inserisce automaticamente una chiamata al costruttore di default della classe base aggiungendo la chiamata a super() In questo caso il costruttore dei default della classe base deve esistere, altrimenti si ha ERRORE.

EREDITARIETÀ E COSTRUTTORI E se non indichiamo alcuna chiamata a super(... ) ? Il sistema inserisce automaticamente una chiamata al costruttore di default della classe base aggiungendo la chiamata a super() In questo caso il costruttore dei default della classe base deve esistere, altrimenti si ha ERRORE. RICORDA: il sistema genera automatica- mente il costruttore di default solo se noi non definiamo alcun costruttore! Se cè anche solo una definizione di costrut- tore data da noi, il sistema assume che noi sappiamo il fatto nostro, e non genera più il costruttore di default automatico.

super : RIASSUNTO La parola chiave super nella forma super(... ), invoca un costruttore della classe base nella forma super.val, consente di accedere al campo val della classe base (sempre che esso non sia private) nella forma super.metodo(), consente di invocare il metodo metodo() della classe base (sempre che esso non sia private)

COSTRUTTORI e PROTEZIONE Di norma, i costruttori sono public –in particolare, è sempre pubblico il costruttore di default generato automaticamente da java Almeno un costruttore pubblico deve sempre esistere, a meno che si voglia impedire espressamente di creare oggetti di tale classe agli utenti non autorizzati –caso tipico: una classe che fornisce solo costruttori protetti è pensata per fungere da classe base per altre classi più specifiche –non si vuole che vengano istanziati oggetti

EREDITARIETÀ: CONSEGUENZE Se una classe eredita da unaltra, la classe derivata mantiene linterfaccia di accesso della classe base –anche se, naturalmente, può specializzarla, aggiungendo nuovi metodi Quindi, un Counter2 può essere usato al posto di un Counter se necessario Ogni Counter2 è anche un Counter ! Counter eredita_da Counter2

EREDITARIETÀ: CONSEGUENZE Ogni oggetto di classe Counter2 è anche implicitamente di classe Counter ma non viceversa –un Counter è meno ricco di un Counter2 Quindi, lereditarietà è più di un semplice riuso di codice: riusa lastrazione Induce una classificazione del mondo (aderente alla realtà...?) Counter eredita_da Counter2

EREDITARIETÀ: CONSEGUENZE Se ogni Counter2 è anche un Counter, è possibile usare un Counter2 al posto di un Counter senza che il sistema se ne accorga! class Esempio6 { Counter c1 = new Counter(10); Counter2 c2 = new Counter2(20); c2.dec();// OK: c2 è un Counter2 // c1.dec();// NO: c1 è solo un Counter c1=c2; // OK: c2 è anche un Counter // c2=c1; // NO: c1 è solo un Counter }

EREDITARIETÀ: CONSEGUENZE Se ogni Counter2 è anche un Counter, è possibile usare un Counter2 al posto di un Counter senza che il sistema se ne accorga! class Esempio6 { Counter c1 = new Counter(10); Counter2 c2 = new Counter2(20); c2.dec();// OK: c2 è un Counter2 // c1.dec();// NO: c1 è solo un Counter c1=c2; // OK: c2 è anche un Counter // c2=c1; // NO: c1 è solo un Counter } OK perché c2 è un Counter2, quindi anche implicitamente un Counter (e c1 è a sua volta un Counter ) NO, perché c2 è un Counter2, e come tale esige un suo pari, mentre c1 è solo un Counter

EREDITARIETÀ: CONSEGUENZE Dunque, la classe Counter2 definisce un sottotipo della classe Counter –Gli oggetti di classe Counter sono compatibili con gli oggetti di classe Counter2 (perché la classe Counter2 è inclusa nella classe Counter ) –ma non viceversa Ovunque si possa usare un Counter, lì si può usare un Counter2 (ma non viceversa) sottinsieme dei Counter2 insieme dei Counter

EREDITARIETÀ: CONSEGUENZE Dire che ogni Counter2 è anche un Counter significa dire che linsieme dei Counter2 è un sottoinsieme dellinsieme dei Counter ! –Se questo è vero nella realtà, la classificazione è aderente alla realtà del mondo –Se invece è falso, questa classificazione nega la realtà del mondo non è un buon modello del mondo può produrre assurdità e inconsistenze sottinsieme dei Counter2 insieme dei Counter

EREDITARIETÀ: CONSEGUENZE Una sottoclasse dovrebbe dunque delimitare un sottoinsieme della classe da cui deriva: altrimenti, si modella la realtà al contrario! Esempi –Studente che deriva da Persona OK (ogni Studente è anche una Persona) –Reale che deriva da Intero NO (non è vero che ogni Reale sia anche un Intero!) oggetti della sottoclasse oggetti della classe-base

UN ESEMPIO COMPLETO Una classe Persona e una sottoclasse Studente –è aderente alla realtà, perché è vero nel mondo reale che tutti gli studenti sono persone –compatibilità di tipo: potremo usare uno studente (che è anche una persona) ovunque sia richiesta una generica persona ma non viceversa: se serve uno studente, non si può accontentarsi di una generica persona! sottinsieme di Studenti insieme di Persone

LA CLASSE Persona public class Persona { protected String nome; protected int anni; public Persona() { nome = "sconosciuto"; anni = 0; } public Persona(String n) { nome = n; anni = 0; } public Persona(String n, int a) { nome=n; anni=a; } public void print() { System.out.print(Mi chiamo " + nome); System.out.println(" e ho " +anni+ "anni"); }

LA CLASSE Studente public class Studente extends Persona { protected int matr; public Studente() { super(); matr = 9999; } public Studente(String n) { super(n); matr = 8888; } public Studente(String n, int a) { super(n,a); matr=7777; } public Studente(String n, int a, int m) { super(n,a); matr=m; } public void print() { super.print(); System.out.println("Matricola = " + matr); }

LA CLASSE Studente public class Studente extends Persona { protected int matr; public Studente() { super(); matr = 9999; } public Studente(String n) { super(n); matr = 8888; } public Studente(String n, int a) { super(n,a); matr=7777; } public Studente(String n, int a, int m) { super(n,a); matr=m; } public void print() { super.print(); System.out.println("Matricola = " + matr); } Ridefinisce il metodo void print() sovrascrive quello ereditato da Persona è una versione specializzata per Studente che però riusa quello di Persona ( super ), estendendolo per stampare la matricola.

LA CLASSE EsempioDiCittà public class EsempioDiCitta { public static void main(String args[]){ Persona p = new Persona("John"); Studente s = new Studente("Tom"); p.print(); // stampa nome ed età s.print(); // stampa nome, età, matricola p=s; // OK (Studente estende Persona) p.print();// COSA STAMPA ??? } Lassegnamento p=s non comporta perdita di informazione, perché si assegnano riferimenti (gli oggetti puntati rimangono inalterati)

LA CLASSE EsempioDiCittà public class EsempioDiCitta { public static void main(String args[]){ Persona p = new Persona("John"); Studente s = new Studente("Tom"); p.print(); // stampa nome ed età s.print(); // stampa nome, età, matricola p=s; p.print();// COSA STAMPA ??? } PROBLEMA: cosa stampa? p è un riferimento a Persona ma gli è stato assegnato un oggetto Studente Se prevale la natura del riferimento, stamperà solo nome ed età Se prevale la natura delloggetto puntato, stamperà nome, età e matricola È un problema di POLIMORFISMO

POLIMORFISMO Un metodo si dice polimorfo quando è in grado di adattare il suo comportamento allo specifico oggetto su cui deve operare. In Java, la possibilità di usare riferimenti a una data classe –ad esempio, Persona per puntare a oggetti di classi più specifiche –ad esempio, Studente introduce in astratto la possibilità di avere polimorfismo. Ma in pratica?

POLIMORFISMO In pratica, dipende cosa prevale: se prevale il tipo del riferimento, non ci sarà mai polimorfismo –in tal caso, p.print() stamperà solo nome ed età, perché verrà invocato il metodo print() della classe Persona se invece prevale il tipo delloggetto, allora cè polimorfismo –in tal caso, p.print() stamperà nome, età e matricola, perché verrà invocato il metodo print() della classe Studente

POLIMORFISMO In pratica, dipende cosa prevale: se prevale il tipo del riferimento, non ci sarà mai polimorfismo –in tal caso, p.print() stamperà solo nome ed età, perché verrà invocato il metodo print() della classe Persona se invece prevale il tipo delloggetto, allora cè polimorfismo –in tal caso, p.print() stamperà nome, età e matricola, perché verrà invocato il metodo print() della classe Studente Java supporta il Polimorfismo prevale il tipo delloggetto LATE BINDING: le chiamate ai metodi sono collegate alla versione opportuna del metodo al momento della chiamata, in base allogget-to effettivamente referenziato (a run-time)

LA CLASSE EsempioDiCittà public class EsempioDiCitta { public static void main(String args[]){ Persona p = new Persona("John"); Studente s = new Studente("Tom"); p.print(); // stampa nome ed età s.print(); // stampa nome, età, matricola p=s; p.print();// COSA STAMPA ??? } void print() è un metodo polimorfo Poiché p referenzia uno Studente, stampa nome, età e matricola

GERARCHIE DI EREDITARIETÀ La relazione di ereditarietà determina la nascita di gerarchie o tassonomie di ereditarietà In Java, ogni classe deriva implicitamente dalla classe-base Object, che è la radice della gerarchia La frase class A sottintende extends Object A Object B D

Object, LA RADICE DI TUTTO La classe base Object definisce alcuni metodi, ereditati da tutte le altre classi: –clone() –equals() –toString() –... A Object B D

Object, LA RADICE DI TUTTO Alcuni metodi interessanti: protected Object clone() –duplica loggetto su cui è invocato –è un metodo protetto: per rendere disponibile questa funzionalità allesterno di una classe, occorre ridefinirlo come pubblico public boolean equals(Object x) –verifica luguaglianza dei valori di due oggetti public String toString() –crea una rappresentazione delloggetto sotto forma di stringa

ESEMPIO Una piccola classe (eredita implicitamente il metodo toString() da Object ): public class Deposito { float soldi; public Deposito() { soldi=0; } public Deposito(float s) { soldi=s; } }

ESEMPIO... e una classe che la usa: public class Esempio7 { public static void main(String args[]){ Deposito d1 = new Deposito(312); System.out.println(d1); } Per stampare d1, viene invocato automati- camente il metodo toString() È una forma compatta per System.out.println(d1.toString());

ESEMPIO Se il toString() predefinito da Object non soddisfa, si può ridefinirlo: public class Deposito { float soldi; public Deposito() { soldi=0; } public Deposito(float s) { soldi=s; } public String toString() { return "Deposito di valore " + soldi; } } Viene creato un nuovo oggetto String concate- nando la frase Deposito di valore con il risultato di Float.toString(soldi)

ESEMPIO Loutput nel primo caso... e nel secondo caso: Deposito di valore Identificativo univoco generato da Java: nome della classe + indirizzo delloggetto

CLASSI FINALI Una classe finale ( final ) è una classe di cui si vuole impedire a priori che possano essere definite, un domani, delle sottoclassi Esempio: public final class TheLastCounter extends Counter {... }