Programmazione a Oggetti e JAVA Prof. B.Buttarazzi A.A. 2012/2013
Sommario Paradigma O.O. Oggetti e Classi Ereditarietà
Paradigma Object-Oriented Il paradigma O.O. si ispira all ambiente che ci circonda, costituito da oggetti, identificati da: una componente statica, che ne descrive lo stato; una componente dinamica, che ne descrive il comportamento. Tutti gli oggetti che hanno le stesse caratteristiche appartengono ad una stessa classe (insieme). La classe è l entità astratta che rappresenta le caratteristiche (attributi) e i comportamenti (metodi) comuni che avranno gli oggetti generati a partire da essa. Si dice che un oggetto è una istanza (instance) di una classe (cioè un esemplare o caso particolare di una classe) per indicare che questo occupa memoria, a differenza della classe di appartenenza che ne definisce solo il tipo come sono organizzati i dati nella memoria. 3
Paradigma Object-Oriented Esempio (classe Autovettura) 4
Paradigma Object-Oriented Esempio (classe Autovettura) Con la classe Autovettura è possibile creare (istanziare) oggetti distinti: le autovetture concrete. Gli oggetti a differenza della classe ( modello ) avranno gli attributi inizializzati. Autovettura targa marcia colore giri_motore Notazione UML definizione di Classe accendiauto() spegniauto() cambiamarcia(int m) acceleraauto(int a) istance_of istance_of istance_of targa: CE 123 SA marcia: 0 colore: verde girimotore: 0 targa: AB 434 DE marcia: 4 colore: blu girimotore: 5000 targa: XY 823 SF marcia: 0 colore: rosso girimotore: 0 5
targa marcia colore giri_motore Autovettura Notazione UML definizione di Classe accendiauto() spegniauto() cambiamarcia(int m) acceleraauto(int a) istance_of istance_of istance_of targa: CE 123 SA marcia: 0 colore: verde girimotore: 0 targa: AB 434 DE marcia: 4 colore: blu girimotore: 5000 targa: XY 823 SF marcia: 0 colore: rosso girimotore: 0 6
Paradigma Object-Oriented Esempio (classe Persona) Classe per le persone : nome, cognome e città di residenza. 7
Paradigma Object-Oriented Con la classe Persona è possibile creare (istanziare) oggetti: le persone concrete. A differenza del modello avranno gli attributi inizializzati La relazione che esiste tra gli oggetti (p1, p2 e p3) e la classe che li ha generati è detta instance_of (istanza_di). 8
9
Paradigma Object-Oriented Consuetudini: i nomi delle classi sono al singolare con l iniziale maiuscola; i nomi dei metodi iniziano sempre con la lettera minuscola: se sono composti le successive parole hanno l iniziale maiuscola; i nomi degli attributi sono sempre minuscoli: se composti da più parole, queste sono separate con il carattere sottolineatura ( _ ). Per le rappresentazioni grafiche si utilizza l UML (Unified Modeling Language). <Classe> <attributi> Componente Statica Componente Dinamica <metodi> 10
Paradigma Object-Oriented Esempio (classe Persona) Classe per le persone fisiche: nome, cognome e città di residenza. Persona + String nome + String cognome - String città i nomi delle classi sono al singolare con l iniziale Maiuscola i nomi degli attributi sono sempre minuscoli: se composti da più parole, queste sono separate con il carattere sottolineatura ( _ ).; + setcitta( String c ) i nomi dei metodi iniziano sempre con la lettera minuscola: se sono composti le successive parole hanno l iniziale maiuscola; La regola di visibilità (scope) specifica se e come si può avere accesso agli elementi della classe: il carattere + specifica uno scope public: elemento visibile a tutti il carattere - lo scope private: elemento invisibile. 11
Principi Object Oriented Incapsulamento. E la capacità di una classe di incapsulare insieme dati e operazioni sui dati Information Hiding Nascondere attributi e operazioni che rappresentano l implementazione. Mostrare solo le operazioni che devono essere visibili dagli altri oggetti. Ereditarietà E la possibilità di derivare una classe da una classe esistente ereditando da quest ultima attributi e operazioni. La classe derivata è detta sottoclasse, la classe esistente superclasse. La sottoclasse può definire nuovi attributi e operazioni e ridefinire attributi e operazioni della superclasse sovrascrivendoli (Overriding) Polimorfismo Dal greco pluralità di forme : è la capacità di una entità di assumere forme diverse a seconda del contesto. In Java ci sono 2itipi di polimorfismo : overloading (eseguire,per una operazione, implementazioni diverse a seconda del contesto) e overriding 16/01/2013 12
Programmazione O.O. in Java Nell approccio orientato agli oggetti invece di modellare il problema adattandolo alla logica del calcolatore (specificando le singole azioni da compiere) si definiscono le classi necessarie a risolvere il problema (o si usano classi già disponibili) nel main si creano oggetti a partire dalle classi definite si utilizzano i metodi degli oggetti (gli oggetti possono interagire tra loro) per produrre risultati.
Esercizio Realizzare la classe Frazione secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testfrazione che verifichi il codice scritto. Un oggetto di tipo Frazione contiene una coppia di informazioni elementari: num e denom di tipo int. Deve essere possibile creare un nuovo oggetto Frazione a partire dai campi num e denom. Deve essere possibile sommare alla frazione di riferimento un altra frazione tramite il metodo somma. In particolare si tenga conto che il metodo somma consente di sommare 2 frazioni: la frazione oggetto di riferimento (es. f1) e un altra frazione (es. f2) e assegnare il risultato alla frazione somma (es. f3). va definito un metodo String tostring() che restituisce una descrizione testuale adeguata della frazione. Frazione - int num - int denom + Frazione(int num, int denom) + Frazione somma(frazione frazione) + int getnumeratore() + int getdenominatore() + String tostring ()
Esercizio Realizzare la classe Frazione secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testfrazione che verifichi il codice scritto. Costruttore Deve essere possibile creare un nuovo oggetto Frazione a partire dai campi num e denom - int num - int denom Frazione + Frazione(int num, int denom) + Frazione somma(frazione frazione) + int getnumeratore() + int getdenominatore() + String tostring ()
Esercizio Realizzare la classe Frazione secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testfrazione che verifichi il codice scritto. Metodo somma Deve essere possibile sommare alla frazione di riferimento un altra frazione tramite il metodo somma. In particolare si tenga conto che il metodo somma consente di sommare 2 frazioni: la frazione oggetto di riferimento (es. f1) e un altra frazione (es. f2) e assegnare il risultato alla frazione somma (es. f3). Frazione f3; Frazione f3=f1.somma(f2); Frazione - int num - int denom + Frazione(int num, int denom) + Frazione somma(frazione frazione) + int getnumeratore() + int getdenominatore() + String tostring ()
Esercizio Realizzare la classe Frazione secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testfrazione che verifichi il codice scritto. Metodo somma Deve essere possibile sommare alla frazione di riferimento un altra frazione tramite il metodo somma. In particolare si tenga conto che il metodo somma consente di sommare 2 frazioni: la frazione oggetto di riferimento (es. f1) e un altra frazione (es. f2) e assegnare il risultato alla frazione somma (es. f3). Frazione f3=new Frazione (0,0); f3=f1.somma(f2); Frazione - int num - int denom + Frazione(int num, int denom) + Frazione somma(frazione frazione) + int getnumeratore() + int getdenominatore() + String tostring ()
Esercizio Realizzare la classe Frazione secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testfrazione che verifichi il codice scritto. I metiodi get implementano l incapsulamento relativo la classe Frazione. - int num Frazione Possiamo notare che le variabili num e denom essendo state dichiarate private, non saranno accessibili da classi esterne. L accesso alle variabili num e denom viene effettuato dai metodi, getnumeratore e getdenominatore che operano in lettura. Va definito un metodo String tostring() che restituisce una descrizione testuale adeguata della frazione. - int denom + Frazione(int num, int denom) + Frazione somma(frazione frazione) + int getnumeratore() + int getdenominatore() + String tostring ()
public class Frazione { private int numeratore; private int denominatore; public Frazione(int numeratore, int denominatore){ this.numeratore=numeratore; this.denominatore=denominatore; public int getnumeratore(){ return this.numeratore; public int getdenominatore(){ return this.denominatore;
public Frazione somma(frazione frazione){ int den=this.denominatore*frazione.denominatore; int num=((frazione.denominatore)*this.numeratore) +(frazione.numeratore*this.denominatore); Frazione f=new Frazione(num,den); return f; public String tostring(){ return (this.numeratore+"/"+this.denominatore); f1 f2 f3 esempio
public class testfrazione { /** * @param args */ public static void main(string[] args) { // TODO Auto-generated method stub Frazione f1=new Frazione(1,3); Frazione f2=new Frazione(2,5); Frazione f3=f1.somma(f2); System.out.println(f1.toString()); System.out.println(f2.toString()); System.out.println(f3.toString());
public class testfrazione { /** * @param args */ public static void main(string[] args) { // TODO Auto-generated method stub Frazione f1=new Frazione(1,3); Frazione f2=new Frazione(5,5); Frazione f3=new Frazione (0,0); f3=f1.somma(f2); System.out.println(f1.toString()); System.out.println(f2.toString()); System.out.println(f3.toString()); in alternativa
Esercizio Realizzare la classe MioArray secondo le informazioni presenti nel diagramma delle Classi UML in figura e scrivere un metodo testarrayche verifichi il codice scritto. MioArray - int num[] - int length + MioArray(int num []) + int somma() + int stampa()
Esercizio MioArray public class MioArray{ int num[]; int length; variabili di istanza MioArray(int a[]){ num=a; length=num.length; public int somma(){ int res=0; for(int k=0;k<num.length;k++){ res=res+num[k]; return res; public void stampa(){ if(num.length==0) return; System.out.print("l'array = "+num[0]); for(int i=1; i<num.length; i++){ System.out.print(", "+num[i]); System.out.println(); costruttore metodo metodo
Esercizio MioArray public int prodotto(){ int res=1; for(int k=0;k<num.length;k++){ res=res*num[k]; return res; public int massimo(){ int max=num[0]; for(int k=0;k<num.length;k++){ if(num[k]>max) max=num[k]; return max; metodo metodo
class EsempioArray2{ public static void main(string args[]){ int v[]={2,9,54,12,45,78; MioArray a=new MioArray(v); int somma=a.somma(); double media=somma/a.length; System.out.println("L'array utilizzato:"); //stampa gli elementi dell'array a.stampa(); System.out.println("media ="+media); System.out.println("media ="+a.massimo()); Esercizio MyArray
Ereditarietà L'ereditarietà è un meccanismo fondamentale per il riutilizzo del codice nella programmazione a oggetti. Infatti tramite questo meccanismo è possibile estendere e potenziare classi già esistenti. In Java si usa l ereditarietà quando occorre definire una classe i cui oggetti hanno una struttura più ricca di quella di una classe già definita, oppure che realizzano delle funzionalità aggiuntive. La nuova classe più "specializzata" che eredita i campi e i metodi dalla classe preesistente viene detta Sottoclasse. La classe più "generale" (quella preesistente) si dice Superclasse. Si dice che la sottoclasse estende la superclasse.
Ereditarietà
Nuovo tipo di modificatore di visibilità!
esempio di oveloading
Overloading L'overloading rappresenta una importante caratteristica di Java che consente ad una classe di avere più metodi con lo stesso nome ma con parametri differenti ovvero con una firma diversa. Overload significa «sovraccaricare» ovvero definire più versioni di un metodo, utilizzando lo stesso nome ma una firma diversa. Per firma di un metodo si intende il numero e/o il tipo di argomenti nella dichiarazione. Infatti sulla base degli argomenti passati in fase di chiamata verrà riconosciuta la firma e richiamato il metodo corretto.
La qualifica protected: rende accessibile un campo a tutte le sottoclassi, presenti e future costituisce perciò un permesso di accesso valido per ogni possibile sottoclasse che possa essere definita.
L espressione super(...) invoca il costruttore della classe base, quindi deve avere i parametri attuali corrispondenti in numero e tipo a quelli formali. L espressione super.print() invoca il metodo print della classe base.
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)
Cosa abbiamo imparato? Il concetto di Ereditarietà; La differenza tra superclasse e sottoclasse; La qualifica protected; A cosa serve la parola chiave super. 16/01/2013 36
Questionario 1) Quali sono le proprietà fondamentali della programmazione OO? Ereditarietà, incapsulamento, polimorfismo, overloading e overriding; Incapsulamento, overloading e overriding; Ereditarietà, incapsulamento e polimorfismo; Ereditarietà, polimorfismo, overloading e overriding. 2) Quali delle seguenti non è una fase fondamentale della programmazione Object- Oriented? Utilizzare l incapsulamento dei metodi, che attraverso l overloading permette ad una classe di avere più metodi con lo stesso nome e con parametri differenti; Definire le classi; Utilizzare il polimorfismo dei metodi, che attraverso l overloading permette ad una classe di avere più metodi con lo stesso nome ma con parametri differenti; Implementare l information hiding. 16/01/2013 37
3) Che cos è l ereditarietà? E la tecnica che permette l accesso diretto a tutti gli attributi privati, rendendo la classe indipendente e riutilizzabile E la tecnica che permette ad una classe di incorporare nella sua dichiarazione un altra classe; E la tecnica che permette ad un interfaccia di accedere ad una classe generica di azioni; E la tecnica che permette di avere più metodi e costruttori all interno di una stessa classe con le stesse variabili d istanza. 4) Una Superclasse ha accesso ai membri di una sottoclasse? E una sottoclasse ha accesso ai membri di una Superclasse? Una superclasse ha accesso ai membri di una sottoclasse, ed anche una sottoclasse può accedere a tutti i membri non privati della sua superclasse; Una superclasse ha accesso ai membri di una sottoclasse, ma una sottoclasse non può accedere ai membri della sua superclasse; Una superclasse non ha accesso ai membri di una sottoclasse, ma una sottoclasse può accedere a tutti i membri non privati della sua superclasse; Una superclasse non ha accesso ai membri di una sottoclasse, ma una sottoclasse può accedere a tutti i membri della sua superclasse. 16/01/2013 38
5) Quando si crea una sottoclasse, quale o quali parole chiave vengono utilizzate per includere una superclasse? Estend; Super e Extends; Super; Extends. 6)Analizzare la seguente parte di programma: class ScatolaPeso extends Scatola{ private int peso; public ScatolaPeso(int a,int l,int p,int pe){ super (a,l,p); peso=pe; Per quale funzione viene utilizzato, in questa caso, la parola chiave super? Per invocare il costruttore della classe base; Per invocare un metodo della classe base; Per accedere ad un campo della classe base; Per accedere ai membri della superclasse. 16/01/2013 39
7) Per quale delle seguenti funzioni non può essere utilizzata la parola chiave super? Per accedere ai membri della superclasse; Per incorporare nella dichiarazione di una classe quella di un altra; Per invocare un metodo della classe base; Per invocare il costruttore della classe base. 8) Quale dei seguenti non è un modificatore di accesso? Private ; Public; Default; Protect. 16/01/2013 40
Esercizio Classe Punto su piano cartesiano Implementare una classe Java che rappresenti un punto nel piano cartesiano. La classe Punto è caratterizzata dalle sue coordinate (due valori di tipo double) e fornisce i seguenti metodi: un costruttore di default (nessun parametro): inizializza le coordinate con i valori (0,0) un costruttore che prenda come parametri due valori double e li imposti come coordinate del punto void sposta(double x, double y): imposta i valori dei parametri x e y come nuove coordinate del punto boolean coincide(punto p): verifica se il punto p coincide con il punto istanza su cui viene invocato il metodo (due punti sono coincidenti quando hanno le stesse coordinate) boolean simmetricox(punto p): verifica se il punto passato come parametro èsimmetrico al punto corrente rispetto all'asse x (ovvero se le coordinate x dei due punti sono uguali e la coordinata y del punto passato come parametro è l'opposto della coordinata y dell'oggetto istanza di invocazione). boolean simmetricoy(punto p): verifica se il punto passato come parametro è simmetrico al punto corrente rispetto all'asse y (ovvero se le coordinate y dei due punti sono uguali e la coordinata x del punto passato come parametro è l'opposto della coordinata x dell'oggetto istanza di invocazione). tostring: restituisce una stringa che descrive il punto nel formato (x,y) in cui x e y sono le coordinate correnti del punto. La classe deve essere opportunamente incapsulata (cioè deve fornire anche i metodi get* ed set* per le coordinate del punto). Verificare la correttezza del codice compilando ed eseguendo una classe di prova. Si produca anche lo schema UML
Esercizio Classe Punto su piano cartesiano Implementare una classe Java che rappresenti un Libro. La classe Libro è caratterizzata dal titolo (stringa) e da un array di stringhe contenenti i nomi degli autori e fornisce i seguenti metodi: aggiungiautore(s) che presa in ingresso un stringa s la inserisce nell'array contenente i nomi degli autori, in modo che il nome dell'i-esimo autore inserito occupi la posizione corrispondente dell'array. numeroautori() che restituisce il numero degli autori del libro. getautore(i) che dato un intero i, restituisce l'autore in posizione i nell'array degli autori. tostring() che restituisce una stringa rappresentante il libro, scrivendo il titolo sulla prima riga e l'elenco degli autori separati da una virgola sulla seconda. La classe deve essere opportunamente incapsulata (cioè deve fornire anche i metodi get* ed set* ). Verificare la correttezza del codice compilando ed eseguendo una classe di prova. Si produca anche lo schema UML