Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI [email protected].

190
Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI [email protected]

Transcript of Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI [email protected].

Page 1: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

Introduzione alla Object Oriented Programming, OOP

E.Mumolo. DEEI

[email protected]

Page 2: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

2

Prima parte: il C++ come estensione del C

Page 3: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

3

Paradigmi di programmazione

• Modello procedurale• Il mondo della programmazione viene visto come un sistema di processi

• Modello ad oggetti• Il mondo viene visto come un sistema di cose

• Alcuni temi tipici del modello procedurale:• Processi• Sequenze di esecuzione• Diagrammi di flusso• Programmazione top-down• Programmazione strutturata• Algoritmi=strutture dati + programmazione strutturata

• Linguaggi strutturati:Fortran, Cobol, Basic, Pascal, C …• Operazioni effettuate sui dati inviate alle procedure e alle funzioni sistemi

software validi ed efficienti per basse complessità MA : ad alte complessità si evidenzia un cedimento del sistema

• Una modifica di una struttura dati ha grandi effetti sul sistema campo di visibilità delle strutture dati

• Riusabilita’ nei lnguaggi procedurali

Page 4: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

4

Struttura di un programma

• Spaghetti code

• Programmazione strutturata

Page 5: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

5

Il linguaggio C++

• sviluppato alla AT&T da B.Stroustrup (1980) da una idea di Simula65.• estensione del C• astrazione dei dati • Pro:

• estensione rispetto al linguaggio C

• Piu adatto del C a progetti complessi

• prestazioni elevate nonostante la complessità

• molteplici produttori

• Contro:• linguaggio complesso (non elimina le ridondanze di C, anzi ne introduce)

• linguaggio ibrido: consente di continuare sviluppare codice tradizionale in C

• non aiuta a programmare ad oggetti

• recupero manuale della memoria (Garbage Collection) 

Page 6: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

6

Estensione del C• commenti: delimitati da // per commenti su una riga, oltre a /* … */ più adatti

a commenti su più righe • costanti: variabili di sola lettura specificatore const

#include <iostream.h> //oop1.cpp main() { const int i=1; const int *pi=&i; const double pg=3.1415926; char str[]="giorgio"; char str1[]="luigi"; const char *n; //n e' un puntatore ad una stringa costante n=str; n=str1; //n puo' essere cambiato cout << n << '\n'; // *n="antonio"; ILLEGALE: il dato puntato da n e' costante e non puo' essere cambiato char *const a = str; //a e' un puntatore costante a char //a deve essere inizializzato e non puo' essere cambiato // a=str1; ILLEGALE: il puntatore non puo' essere cambiato cout << "i=" << i << " *pi=" << *pi << " pg*i=" << pg**pi << " nome=" << a <<'\n'; const char const*c = str1; //sia il puntatore che il valore puntato sono costanti!! cout << c << '\n'; } Output del programma luigi i=1 *pi=1 pg*i=3.14159 nome=giorgio luigi

Page 7: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

7

• Dichiarazioni variabili: non solo all’inizio del programma, ma anche nei cicli

• Definizione di struttura, enum, unione

for(int i=0; i<N; i++) {...}

//oop2.cpp #include <iostream.h> enum logico { falso, vero }; struct valore { int dato; float somma; logico var; union // unione senza nome: lo spazio occupato e' quello dell'elemento piu' grande! {

float val; char a[10]; logico p; }; }; main() { valore i, j, k[500]; // non serve struct valore!! logico a, b, c[50]; // non serve enum!! i.dato=10; j.somma=20; i.var=vero; i.val=3.14; strcpy(j.a,"PROVA!!"); a=vero; b=falso; cout<<"i.dato="<<i.dato<<" j.somma="<<j.somma<<'\n'<<" stringa="<<j.a<<'\n'; if(a==vero) cout << " logico a=vero\n"; else cout << " logico a=falso\n" ; if(b==vero) cout << " logico b=vero\n"; else cout << " logico b=falso\n" ; } Output: i.dato=10 j.somma=20 stringa=PROVA!! logico a=vero logico b=falso

Page 8: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

8

• Riferimenti (specificatore &)• sinonimi (alias) per lo stesso oggetto• il tipo dell’oggetto determina il tipo del riferimento• puo’ essere visto come un tipo speciale di puntatore• deve essere inizializzato e agisce solo su un oggetto• uso principale: argomenti e risultati di una funzione

//oop3.cpp #include <iostream.h> main() { float p; float &rp=p; //rp=riferimento a p (alias di p) p=3.14; rp=6.28; cout << "p =" << p << " rp=" << rp << '\n'; const float &rp1=p; //rp1 e' alias di p, ma l'oggetto riferito e' costante //rp1 non puo' modificare l'oggetto // rp1=3.1; ILLEGALE: non si puo' modificare un oggetto costante! cout << "rp1=" << rp1 <<'\n'; } Output: p =6.28 rp=6.28 rp1=6.28

Page 9: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

9

• Uso dei riferimenti come argomenti e risultati di funzione senza passare esplicitamente l’indirizzo//opp4.cpp

#include <iostream.h>

int incrementa(int &val)

{

val++;

if(val>65000) val=65000;

return 0;

}

int incrementa(int &val, int v)

{

int t=v;

t++;

if(t>65000) t=65000;

return t;

}

main()

{

int i=7;

cout << " i=" << i;

incrementa(i);

cout << " i=" << i << " i=" << incrementa(i,i) << " i=" << i << '\n';

}

Output: i=7 i=8 i=9 i=8

Page 10: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

10

//Altri esempi di alias #include <iostream.h> //oop5.cpp void scambia(int &rx, int &ry) { int t=rx; rx=ry; ry=t; } main() { int x=20; int y=30; cout << "x, y =" << x << ' ' << y; scambia(x,y); cout << "x, y =" << x << ' ' << y; } //oop6.cpp ************************************************************* #include <iostream.h> int &max(int &a, int &b) { if(a>=b) return a; return b; } main() { int x, y; cin >> x >> y; cout << " il massimo tra " << x << " e " << y << "e' " << max(x,y); } Altra versione: int &max(const int &a, const int &b) { if(a>=b) return (int &)a; //il casting e’ necessario per via di const return (int &)b; }

Page 11: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

11

• argomenti di default in una funzione

• specificatore “inline”: inline void funzione(..) sostituisce il codice della funzione alle chiamate di funzione. : attenzione alla crescita delle dimensioni del codice!

• campo di visibilità delle dichiarazioni• identificatori dichiarati nelle funzioni sono visibili dalla dichiarazione fino

alla fine della funzione• identificatori globali sono visibili dalla dichiarazione alla fine del file• identificatore locale maschera un identificatore globale con un stesso nome• Scope o operatore di visibilità “::” specifica la variabile da utilizzare• identificatori locali non sono visibili all'esterno della funzione• l’identificatore “::var” identifica la variabile globale• blocco: sequenza di istruzioni tra graffe

//opp7.cpp #include <iostream.h> void build(float *val, int size=10) { for(short i=0; i<size; i++) val[i]=(float)i; } main() { float A[100]; int N=10; build(A); //non e' necessario usare build(A,N): viene usato il valore di default for(short i=0; i<10; i++) cout << A[i] << ' '; }

Page 12: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

12

• una funzione e’ un blocco• visibilita’ locale: identificatori definiti all’interno di un blocco• visibilita’ a livello di file: funzioni e identificatori definiti fuori da tutte le

funzioni• visibilita’ degli identificatori di blocchi annidati• visibilita’ delle etichette: nel corpo della funzione a cui il blocco appartiene

//oop8.cpp #include <iostream.h> int a=1; main() {

int aext=a; int a=2; { int aext=a; int a=3; { int aext=a; int a=4; cout << "exta=" << aext << " interno a=" << a << " ::a=" << ::a << endl; } cout << "aext=" << aext << " esterno a=" << a << " ::a=" << ::a << endl; } cout << "aext=" << aext << " main a=" << a << " ::a=" << ::a << endl; } Output: aext=3 interno a=4 ::a=1 aext=2 esterno a=3 ::a=1 aext=1 main a=2 ::a=1

Page 13: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

13

• Allocazione di oggetti dinamici nella memoria libera• Operatore new: argomento tipo dell’oggetto e ritorna un puntatore all’oggetto

• New restituisce un puntatore nullo in caso di errore

• Per allocare un array indicare tipo e numero di elementi

• Operatore delete: rilascia un oggetto in memoria libera

• Per rilasciare un array: specificatore []//oop9.cpp #include <iostream.h> main() { int *dati; int dim; cout << "dimensione array?" ; cin >> dim; dati= new int[dim]; for(short i=0; i<dim; i++) dati[i]=i; for(short i=0; i<dim; i++) cout << dati[i] << ' '; delete []dati; } //oop10.cpp #include <iostream.h> main() { int dim; char *nome; cout << "quanti caratteri ha il nome?"; cin >> dim; nome=new char[dim+1]; cout << endl << "scrivi il nome "; cin >> nome; cout << "hai scritto " << nome; delete nome; } quanti caratteri ha il nome?7 scrivi il nome Antonio hai scritto Antonio

Page 14: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

14

//oop11.cpp // esempi di riepilogo: gestione di liste semplici #include <iostream.h> struct nodo { int dato; nodo *next; }; enum booleano { falso, vero }; nodo *crea(int n) { nodo *p, *p0=0; for(int i=1; i<=n; i++) { p=new nodo; cout << "scrivi un numero "; cin>> p->dato; p->next=p0; p0=p; } return p0; } void insert(nodo *&p0, int a) { nodo *p=new nodo; p->dato=a; p->next=p0; p0=p; } booleano estraitesta(nodo *&p0, int &a) { nodo *p=p0; if(p0==0) return falso; a=p0->dato; p0=p0->next; delete p; return vero; }

Page 15: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

15

void accoda(nodo *&p0, int a) { nodo *p, *q; for(q=p0;q!=0;q=q->next) p=q; q=new nodo; q->dato=a; q->next=0; if(p0==0) p0=q; else p->next=q; } booleano estraicoda(nodo *&p0, int &a) { nodo *p=0, *q; if(p0==0) return falso; for(q=p0;q->next != 0; q=q->next) p=0; q=q->next; if(q==p0) p0=0; else p->next=0; delete q; return vero; } main() { int a; char c; nodo *r, *p; p=crea(3); for(int i=1; i<3; i++) { cout << " scrivi un numero "; cin >> a; insert(p,a); accoda(p,a); } while(estraitesta(p,a)==vero) cout << "valore=" << a << endl; }

Page 16: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

16

//oop12.cpp //Riepilogando: gestione di alberi binari #include <iostream.h> struct nodo { int dato; nodo *sx; nodo *dx; }; nodo * inserisci(nodo *r, int d) { if(r==0) { r=new nodo; r->dato=d; r->sx=0; r->dx=0; } else if(d<r->dato) r->sx=inserisci(r->sx,d); else if(d>r->dato) r->dx=inserisci(r->dx,d); return r; } void simmetrico(nodo *r) { if(r!=0) { simmetrico(r->sx); cout << r->dato; simmetrico(r->dx); } } void anticipato(nodo *r) { if(r!=0) { cout << r->dato; anticipato(r->sx); anticipato(r->dx); } }

Page 17: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

17

void differito(nodo *r) { if(r!=0) { differito(r->sx); differito(r->dx); cout << r->dato; } } main() { nodo *rad, *p; int a; for(short i=0; i<10; i++){ cout << "dare un numero " ; cin >> a; p=inserisci(p,a); } cout << endl << "visita in ordine simmetrico" << endl; simmetrico(p); cout << endl << "visita in ordine anticipato" << endl; anticipato(p); cout << endl << "visita in ordine differito" << endl; differito(p); } Output 4 3 2 1 8 6 9 5 3 7 visita in ordine simmetrico 123456789 visita in ordine anticipato 432186579 visita in ordine differito 123576984

Page 18: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

18

//esempio di programmazione C++ : bubble sorting//oop13.cpp#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>

float arry[10]={15.5, 44, 0.5, -1.5, 65, 0.0, 55.5, 67.0, 5, 3};

struct sistema{ float *aa; int ord;};

const int ord=10, ord1=5, ord2=4; // variabili non modificabili!

int bubble(float *, int N=ord);void scambia(float &, float &); // passaggio per riferimentovoid stampa(int);void stampa(float *a, int n=ord);

main(){ sistema SS[ord1]; // definisce l'array SS di 5 strutture 'sistema' sistema *sis = new sistema[ord2]; // alloca in mem. lib. un array di 4 strutture

int nl;

Page 19: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

19

//carica le strutture

for(short i=0;i<ord1;i++){

SS[i].aa = new float[ord]; //alloca nella memoria libera

for(short j=0; j<ord;j++) SS[i].aa[j]=float(random(100));

}

for(short i=0;i<ord2;i++){

sis[i].aa = new float[ord];

for(short j=0; j<ord;j++) sis[i].aa[j]=float(random(100));

}

//primo caso

cout << "\nPrimo caso“ << endl;

for(short i=0;i<ord1;i++){

printf("\n\nArray originale %d:\n", i);

for(short j=0;j<ord;j++) cout << SS[i].aa[j] << " "; cout ; // shortnl=bubble(SS[i].aa); // argomento di default

printf("\nArray ordinato (nr. cicli=%d):\n", nl);

for(short j=0;j<ord;j++) cout << SS[i].aa[j] << " "; cout ; // short

}

cout << "\n\nSECONDO CASO“ << endl;

for(short i=0;i<ord2;i++){

printf("\n\nArray originale %d:\n", i);

stampa(sis[i].aa);

nl=bubble(sis[i].aa); //argomento di default: l'ordine dell'array

stampa(nl); //overloading di funzioni e valori default

stampa(sis[i].aa); //overloading di funzioni e valori default

}

}

Page 20: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

20

int bubble(float *A, int N)

{

char *flag="notsorted";

int nloop=0;

while(!strcmp(flag, "notsorted")){

flag="sorted"; nloop++;

for(short i=0;i<N-1;i++)

if(*(A+i) > *(A+i+1)){ //A[i] e' *(A+i)

scambia(*(A+i),*(A+i+1)); //passa per riferimento!! flag="notsorted";

}

}

return nloop;

}

void scambia(float &a, float &b) // il compilatore passa l'indirizzo delle var.

{

float temp=a;

a=b; b=temp;

}

void stampa(int n)

{

printf("\nArray ordinato (nr. cicli=%d):\n", n);

}

void stampa(float *a, int n)

{

for(short j=0;j<n;j++) cout << a[j] << " "; cout ; // definizione short

}

Page 21: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

21

• Sovrapposizione delle funzioni (overloading)• stesso nome per funzioni diverse, che devono avere argomenti diversi in numero e tipo• lo stesso nome deve avere lo stesso tipo di risultato

//oop14.cpp #include <iostream.h> float media(float *a, int size=10) { float somma=0; for(short i=0; i<size; i++) somma+=a[i]; return somma/size; } float media(int *a, int size=10) { int somma=0; for(short i=0; i<size; i++) somma+=a[i]; somma=somma/size; return (float)somma; } main() { int N=10; int a; int buf[10]; float buff[10]; for(short i=0; i<N; i++){ cout << endl << "scrivi un numero intero "; cin >> a; buf[i]=a; buff[i]=a; } cout << "media float=" << media(buff) << endl; cout << "media int=" << media(buf) << endl; }

Page 22: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

22

Seconda parte:Il C++ come linguaggio di programmazione ad oggetti

Page 23: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

23

Il modello ad oggetti

• Alcuni temi tipici

• Dalla astrazione funzionale alla astrazione dei dati

• Il mondo e’ modellato non come processi, ma cose

• Societa’ di entita’ attive, cooperanti, riusabili

• Progettazione bottom-up non top-down

• Modelli di classi, sottoclassi, istanze di oggetti

• Linguaggi ad oggetti: Simula, Smalltalk, Eiffel, C++, Java

• OOP: incapsulamento e mascheramento dei dati

• limitazione del campo di visibilità delle procedure che manipolano i dati

• dati e procedure inseparabili oggetto

• procedure di un oggetto (metodi) attivate inviando messaggi all'oggetto

• gli oggetti inviano messaggi ad altri oggetti

• punti fondamentali: tipi di dati astratti, classe, oggetti, incapsulamento, gerarchie di tipi (sottoclassi), ereditarietà, polimorfismo

Page 24: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

24

• OOP focalizza l'attenzione sui dati da manipolare, piuttosto che sulle procedure• obiettivi della progettazione e realizzazione di software mediante OOP :

• migliorare la produttività del programmatore• aumentare la versatilità e la riutilizzazione del software• controllare la complessità• diminuire il costo di manutenzione

• oggetto = contenitore che racchiude dati e funzioni che gestiscono i dati • Information hiding: capacità di oggetti di racchiude dati per eliminare

accessi indebiti• interfaccia dell'oggetto: indica e pubblicizza le operazioni autorizzate

ad accedere i dati• implementazione delle funzioni (codice): è in genere nascosto

all'interno dell'oggetto• un oggetto riceve delle richieste e risponde alle stesse

Page 25: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

25

• classe = definizione astratta delle caratteristiche degli oggetti• gli oggetti sono tra loro distinti anche se derivano dalla stessa classe• creazione di un oggetto: definizione di una variabile appartenente ad una

determinata classe, o definizione di un oggetto di tipo classe nella memoria libera

• l'interfaccia di una classe è costituita da tutto ciò che non è nascosto in un oggetto. L'interfaccia resta in genere inalterata nel tempo

• operare con gli oggetti :• divisione in componenti che contengono dati e procedure che operano sui dati • un oggetto contiene quindi sia la struttura dati che le procedure (metodi) che

definiscono il comportamento dell'oggetto stesso• le strutture dati sono nascoste all'interno degli oggetti• il mondo esterno comunica con i oggetti inviando loro delle richieste• (messaggi) per informare l'oggetto su quello che deve essere fatto non su come

viene fatto• suddivisione del software in classi: un sistema di archiviazione viene chiamato

classe archivio con struttura dati e metodi per modificare dati

• operare con gli oggetti :• ogni procedura e’ associata ad una classe• se si aggiungono funzioni di un insieme esistente, si può creare una sottoclasse,

creare una nuova classe, o aggiungerle alla classe esistente• struttura gerarchica di tipi e sottotipi mediante scomposizione top-down o

bottom-up: identificazione e rappresentazione dei dati piu’ importanti del sistema tramite classi.

Page 26: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

26

• Top-down: esempio

• Bottom-up:

Classe base(componente complesso)

Sottoclassi (componenti minime)

Automobile

ruota carrozzeria motore

Classe base(componente minimo)

Sottoclassi (componenti via via piu’ complesse)

veicolo

Veicolo senza motore

Veicolo a motore

moto auto

taxi

aereo

Specializzazione

Gen

eral

izza

zion

e

Page 27: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

27

Classi

• Una classe (ADT):class casa{ ... };

• Un oggetto e’ una istanza della classe: casa a;• Piu’ oggetti hanno diversi valori delle variabili e stesso comportamento• Piu’ oggetti hanno diverse variabili, il codice e’ rientrante:

casa a, mia, tua;

• mia.metodo1; //attiva metodo1 mediante l’invio dell’indirizzo di mia al codice di metodo1

• Comunicazione tra oggetti tramite invio di messaggi di attivazione

Campo variabiliMetodo1Metodo2Metodo3

privato

pubblico

var. a var. mia var. tua

Codice dei metodi

Puntatore ‘this’Puntatore ‘this’

Page 28: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

28

Comunicazione tra oggetti

Campo variabiliMetodo1Metodo2Metodo3 Campo variabili

Metodo1Metodo2Metodo3

Campo variabiliMetodo1Metodo2Metodo3

a

tua

mia

Chiama tua.metodo2

Chiama mia.metodo1

Page 29: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

29

In conclusione

• Il mondo visto come sistema ad oggetti:

societa’ di entita’ attive, cooperanti, riutilizzabili

• Progettazione bottom-up

• Ereditarieta’, polimorfismo

• Visione globale

Page 30: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

30

Le classi in C++• una classe è il modello-prototipo-al quale si conformano gli oggetti che

istanziano la classe• struttura di una classe:

 class nome_classe{

private:// dati e metodi accessibili solo ai metodi della classe. Sono quindi nascosti all’esterno (non accessibili direttamente)protected:// privati all’esterno; dati e metodi accessibili solo all’interno della classe e tramite classi derivate public:// dati e metodi accessibili pubblicamente a tutte le funzioni dello stesso scope dell’oggetto

};

• le componenti funzionali dichiarati in una struttura possono essere definite all'interno, (inline) o all'esterno

• una classe introduce un nuovo tipo di dati• lo specificatore private è implicito• scope di una classe: visibilita’ dei componenti (funzioni e variabili)• sintatticamente la classe puo’ essere vista come una estensione di struct

Page 31: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

31

• il tipo di dato definito con le classi, in cui cioè la struttura interna è inaccessibile, e dal quale si possano istanziare oggetti manipolabili solo per mezzo delle operazione associate, è detto “tipo di dato astratto” (ADT)

• esempio di tipo di dato astratto “contatore”

//file contatore.hclass contatore{

private:unsigned int valore;

public:contatore(); //un costruttorevoid incrementa();void decrementa();void set(unsigned int n);unsigned int val();

}

  • l'implementazione della classe può essere realizzato in un file separato o inline

 

Page 32: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

32

//oop15.cpp //scrittura dei metodi in linea #include <iostream.h> class contatore { unsigned int valore; public: contatore(){valore=0;}; void inc(){if(valore<65535) valore++;}; void dec(){if(valore>0) valore--;}; void set(unsigned int n){if((valore>=0)&&(valore<65535)) valore=n;}; unsigned int val(){return valore;}; }; //la definizione termina con ‘;’ main() { contatore c1,c2; c2.set(10); for(short i=0; i<10; i++){ c1.inc(); c2.inc(); } cout << "valore finale di c1=" << c1.val() << " finale di c2=" << c2.val(); } Output: Valore finale di c1=10 finale di c2=20

Page 33: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

33

//oop16.cpp Scrittura dei metodi separatamente #include <iostream.h> class contatore //tipicamente le classi sono definite in un header file .h { unsigned int valore; public: contatore(); void inc(); void dec(); void set(unsigned int n); unsigned int val(); }; //la definizione termina con “;” //le definizioni delle funzioni possono essere implementate nello stesso file //in un file separato *.cpp oppure in file diversi contatore::contatore(){valore=0;}; void contatore::inc(){if(valore<65535) valore++;}; void contatore::dec(){if(valore>0) valore--;}; void contatore::set(unsigned int n){if((valore>=0)&&(valore<65535)) valore=n;}; unsigned int contatore::val(){return valore;}; main() { contatore c1,c2; c2.set(10); for(short i=0; i<10; i++){ c1.inc(); c2.inc(); } cout << "valore finale di c1=" << c1.val() << " finale di c2=" << c2.val(); }

Page 34: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

34

//oop17.cpp Le classi in C++ sono un tipo di struttura #include <iostream.h> // per la cout struct persona0 { //tipica dichiarazione di struttura dati in C int eta; //i "campi" sono pubblici per definizione int altezza; int peso; }; class persona1 { //definizione di una classe di oggetti (senza metodi) int eta; //i campi sono PRIVATI per definizione int altezza; int peso; }; class persona2 { //aggiungo i metodi per manipolare i dati private: // parte protetta non visibile all'esterno: SI POTREBBE OMETTERE int eta; int altezza; int peso; public: // parte visibile (interfaccia) void set(int, int, int); // prototipo di metodo void get(int*, int*, int*); // idem come sopra void print() //funzione inline { cout << eta << "\t" << altezza << "\t" << peso << "\n"; } }; /* implementazione dei metodi di persona2 */ void persona2::set(int e, int a, int p) { eta = e; //dentro ai metodi della classe si possono usare altezza = a; // i dati privati peso = p; } void persona2::get(int *e, int *a, int *p) { *e = eta; *a = altezza; *p = peso; }

Page 35: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

35

struct persona3 { // equivalente a class persona2 public: // parte visibile (interfaccia) SI POTREBBE OMETTERE L'ETICHETTA void set(int, int, int); // prototipo di metodo void get(int*, int*, int*); // idem come sopra void print() { cout << eta << "\t" << altezza << "\t" << peso << "\n"; } private: // parte protetta non visibile all'esterno; int eta; int altezza; int peso; }; /* implementazione dei metodi di persona3 (identici a persona2) */ void persona3::set(int e, int a, int p) { eta = e; //dentro ai metodi della classe si possono usare altezza = a; // i dati privati peso = p; } void persona3::get(int *e, int *a, int *p) { *e = eta; *a = altezza; *p = peso; } /* Programma di prova delle classi */ void main() {

persona0 antonio; persona1 luigi; persona2 giulio; persona3 matteo;

antonio.eta = 20; // OK //luigi.eta = 23; //errore giulio.set(20,180,70); // OK giulio.print(); matteo.set(27,170,76); // OK //cout << matteo.eta; // errore int c1, c2, c3; matteo.get(&c1,&c2,&c3); cout<<"eta' di Matteo:"<<c1<<"altezza di Matteo="<<c2<<"peso di Matteo="<<c3<< endl;

}

Page 36: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

36

Osservazioni• i metodi vengono attivati inviando all'oggetto un messaggio con il nome del

metodo usando l’operatore punto “.”:• c1.incrementa();//invia all’oggetto c1 la richiesta di attivare

//incrementa• c1.visualizza();//analogamente

• Puntatore ad oggetto: operatore freccia a destra “->”://oop18.cpp #include <iostream.h> //per la cout #include "contatore.h" //definizioni e metodi della classe contatore precedente contatore::contatore(){valore=0;}; void contatore::incrementa(){if(valore<65535) valore++;}; void contatore::decrementa(){if(valore>0) valore--;}; void contatore::set(unsigned int n){if((valore>=0)&&(valore<65535)) valore=n;}; unsigned int contatore::val(){return valore;}; void main() { contatore c1; contatore *c3=new contatore; cout << "c1=" << c1.val() << "c3=" << c3->val() << endl;; c1.set(10); c3->set(5); cout << "c3->val()=" << c3->val() << endl; for(short i=0; i<10; i++){ c1.incrementa(); c3->incrementa(); } cout << "valore finale di c1=" << c1.val() << " finale di c3=" << c3->val() ; }

Page 37: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

37

Osservazioni (cont.)

• invio di dati ad una procedura vs. invio di un messaggio all'oggetto • ma: quando un oggetto riceve un messaggio, determina come deve essere

elaborato il dato sottostante usando i metodi associati al dato• non posso elaborare direttamente i dati! Es. c1.valore non è possibile• i metodi possono essere definiti anche in più file• la classe contatore potrebbe anche essere realizzata con una struttura:

#include <stdio.h>

struct contatore

{

unsigned int valore;

};

main()

{

contatore c1, c2;

c1.valore++;

c2.valore++;

}

• ma: in questa forma i dati sono pubblici e la funzione principale accede direttamente al dato sottostante

Page 38: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

38

• struttura dati astratta punto

#include <iostream.h> //oop19.cpp class punto { int x,y; //coordinate private public: punto(){x=0; y=0;}; //costruttore di default punto(int a, int b) {x=a; y=b;}; //altro costruttore (overloading delle funzioni) void MuoviPunto(int d1, int d2) { x+=d1; y+=d2; return; } void StampaPunto(){ cout << "x=" << x <<" y=" << y;} }; main() { punto p1;

punto p2(1,2); //attiva il secondo costruttore

p2.MuoviPunto(1,1); //attiva MuoviPunto

p2.StampaPunto(); }

Page 39: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

39

Classi annidate (nested)• classe interna o nested: definita all’interno di un’altra classe• visibilita’:all’interno dello scope della classe che la contiene• classi definite all’interno di una funzione (scope locale) visibile solo

all’interno della funzione#include <iostream.h> //oop20.cpp class outer { private: class inter { public: int x; void init(int n=0); }; inter a,b; public: void init(int, int); void stampa(); }; void outer::inter::init(int n) { x=n; return; } void outer::init(int n1, int n2) { a.init(n1); b.init(n2); return; } void outer::stampa() { cout << "a=" << a.x << " b=" << b.x << endl; return; } main() { outer c1, c2; c1.init(1,1); c2.init(2,2); c1.stampa(); c2.stampa(); }

Page 40: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

40

Costruttori e distruttori delle classi

• necessità di inizializzare le variabili• ciclo di vita di una variabile locale: nello scope in cui e’ definita• ciclo di vita di una variabile dinamica: programma• quando viene generata una variabili di tipo classe, si attiva automaticamente

una funzione che inizializza le variabili della classe: costruttore• quando la variabile termina il suo ciclo di vita viene attivata automaticamente -

se disponibile- una funzione di eliminazione: distruttore (ad esempio delete di variabili nella memoria libera)

• costruttore: funzione con lo stesso nome della classe• non richiede tipo di ritorno

• puo’ avere una lista di argomenti di inizializzazione

• attivata automaticamente quando si crea un'oggetto con new

• sono possibili costruttore diversi, che devono avere liste di argomenti diversi

• costruttore di default: senza argomenti.

Page 41: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

41

• Costruttore di default• funzione senza argomenti formali• chiamata dal compilatore quando viene definita una variabile senza inizializzazione

speciale• nel caso si richeda una inizializzazione speciale costruttore con argomenti

/ / # i nc l ude <i os t r e a m. h> c l a s s s t r i nga { i nt l e n; c ha r *s t r ; publ i c s t r i nga ( ) { l e n=0; } / / c os t r ut t or e di de f a ul t } ma i n( ) { s t r i nga s t r 1, s t r 2; / / a t t i va i l c os t r ut t or e di de f a u l t }

Page 42: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

42

• Costruttore con argomenti: il costruttore da utilizzare dipende dalla lista degli argomenti

• variabili dinamichestringa *ps=new stringa(“iniziale”);

//new attiva il costruttore. Se new fallisce, ps punta a//NULL e il compilatore NON attiva il costruttore

ps->stampa();...

//oop21.cpp #include <iostream.h> class stringa { int len; char *str; public: stringa(){len=0;} //costruttore di default stringa(const char *s) //costruttore con argomenti; { //s punta a stringa costante len=strlen(s); str=new char[len+1]; strcpy(str,s); } stampa(){cout << str;} }; main() { stringa str1; //attiva il costruttore di default stringa str2("Antonio"), str3="Luigi"; //attiva il costruttore con argomenti stringa nome=str2; nome.stampa(); }

Page 43: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

43

• Costruttore con argomenti opzionali:

#include <iostream.h>

class stringa

{

int len;

char *str;

public:

stringa(int a=0, char ch=' ')

{

len=a; str[len]='\0';

if(a>0) {

str=new char[len+1];

for(int i=0; i<len; i++) str[i]=ch;

}

}

};

Page 44: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

44

• distruttori: funzioni che gestiscono la distruzione del contenuto di oggetti• utilizza il nome della classe preceduto da dal carattere ~• attivata automaticamente al termine del ciclo di vita di un'oggetto• in genere usati per rilasciare la memoria dinamica oppure per salvare• informazioni su file• annulla quello fatto dal costruttore• libera la memoria addizionale utilizzata dell'oggetto • libera le risorse locale e chiude i file aperti • libera la memoria dinamica

• il distruttore, come ogni metodo, può essere chiamato esplicitamentestringa *p=new stringa("nome");p-> stringa:: ~stringa();

 

#include <iostream.h> //oop22.cpp class stringa { int len; char *st; public: stringa(const char *s) { //costruttore st=new char [strlen(s)+1]; len=strlen(s); } ~stringa(){ //distruttore if(len>0) delete st; } }; main() { stringa *p=new stringa("nome"); //attiva il costruttore delete p; //elimina lo spazio dell'oggetto, non la stringa nell'heap }

Page 45: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

45

//esempio di ADT nodo ADT lista//oop23.cpp#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>

class nodo{

private: nodo *next;

int valore; public: nodo(){next=NULL;} void loadn(nodo *a){next=a;} void loadv(int a){valore=a;} nodo *getn(){return next;} int getv(){return valore;}};class lista{

private: nodo *head; public:

lista(){head=NULL;} //costruttore~lista(){}//distruttore: lasciato per esercizio!

void insert(int n); //at the top void add(int n); //at the bottom int hremove(); //toglie dalla cima int tremove(); //toglie dalla coda void type(); //visita dalla cima e stampa il contenuto};

Page 46: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

46

void lista::insert(int n){

nodo *temp;

temp=new nodo; temp -> loadv(n); temp -> loadn(NULL); if(head) {temp -> loadn(head); head=temp;} else {temp -> loadn(NULL); head=temp;}}

void lista::add(int n){

nodo *temp, *prec;

if(head){ temp=head; while(temp){ prec=temp; temp=temp->getn(); } prec->loadn(new nodo); prec=prec->getn(); prec->loadv(n); prec->loadn(NULL); } else { head=new nodo; head -> loadv(n); head -> loadn(NULL); }}

Page 47: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

47

int lista::hremove()

{

int n;

if(head){

n=head->getv();

head=head->getn();

return(n);

} else return(65536); //65536 means empty

}

int lista::tremove()

{

int n;

nodo *temp, *prec;

temp=head;

if(head){

while(temp->getn()) {

prec=temp;

temp=temp->getn();

}

n=temp->getv(); prec->loadn(NULL);

delete(temp);

return(n);

} else return(65536); //65536 means empty

}

Page 48: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

48

void lista::type()

{

nodo *temp;

temp=head;

while(temp){

cout << temp->getv() << '\n';

temp=temp->getn();

}

}

main()

{

lista L1, L2;

int n;

for(int i=0; i<5; i++) L1.insert(i);

cout << "L1:" << '\n'; L1.type();

L2.add(10); L2.add(100);

cout << "L2:" << '\n'; L2.type();

L1.add(5); L1.add(6); L1.add(7);

cout << "L1 after add" << '\n';

L1.type();

cout << "L1hrem " << L1.hremove() << '\n';

cout << "L1hrem " << L1.hremove() << '\n';

while( (n=L2.tremove())!=65536) cout << "L2 trem " << n << '\n';

while( (n=L1.hremove())!=65536) cout << "L1 hrem " << n << '\n';

}

Page 49: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

49

//esempio di ADT Albero

// File Albero.h#define NULL 0struct nodo{ int dato; nodo *sin,*des; };class Albero{ public: Albero() { radice = NULL; } protected: nodo* radice;};

//file AlbRic.h#include "Albero.h“#include <iostream.h>class AlbRic : public Albero{ public:

AlbRic() {} ~AlbRic() { Cancella(radice); } void Inserisci(int i) { Aggiungi(i,radice); } void Visita(){ Differito(radice); }

private: void Cancella(nodo * &p);

void Aggiungi(int i, nodo* &p); void Differito(nodo *p);

};

Page 50: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

50

// File oop24.cpp#include "AlbRic.h"void AlbRic::Cancella(nodo* &p){

if(p!=NULL) {Cancella(p->sin);Cancella(p->des);delete p;

}}void AlbRic::Differito(nodo * p){

if(p!=0){

Differito(p->sin);Differito(p->des);cout << p->dato << " ";

}}void AlbRic::Aggiungi(int i, nodo* &p){

if (p == NULL) { p = new nodo; p->dato = i; p->sin = NULL; p->des = NULL; } else if (i < p->dato) Aggiungi(i,p->sin); else if (i > p->dato) Aggiungi(i,p->des);}void main(){

AlbRic a; for(int i=0;i<10;i++) a.Inserisci(i);

a.Visita();}

Page 51: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

51

Autoriferimento nelle classi: l'argomento implicito 'this‘• una classe può contenere oggetti di altre classi, puntatori a oggetti di altre

classi, puntatori a oggetti della stessa classe (autoriferimento)• ogni oggetto contiene un puntatore, chiamato this, che contiene l'indirizzo

dell'oggetto stesso• nota: ogni oggetto contiene al proprio interno le variabili definite nella classe,

ma non i metodi: ci possono essere molte istanze di una classe ma una sola istanza delle funzioni

• il puntatore all'oggetto this viene passato implicitamente alle funzioni della classe al momento della loro attivazione, per sapere qual è l'oggetto attivatore

 //oop25.cpp #include <iostream.h> class contatore { unsigned int valore; //privato! // contatore *const this; questa definizione e' creata implicitamente public: contatore(); void inc(); void dec(); void set(unsigned int n); unsigned int val(); }; contatore::contatore(){this->valore=0;}; void contatore::inc(){if(this->valore<65535) this->valore++;}; void contatore::dec(){if(this->valore>0) this->valore--;}; void contatore::set(unsigned int n){ this ->valore=n;}; unsigned int contatore::val(){return this->valore;}; main() { //invariato contatore c1,c2; c2.set(10); for(short i=0; i<10; i++){ c1.inc(); c2.inc(); } cout << "valore finale di c1=" << c1.val() << " finale di c2=" << c2.val(); }

Page 52: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

52

• Possibilità offerta da this: costruire un metodo che ritorna il puntatore al metodo che attivato la funzione

#include <iostream.h>//oop26.cppclass punto{

int x,y; // il compilatore inserisce in modo nascosto:punto *const this;//const perché si vieta alla funzione di alterarne il valore

public: punto(){x=0; y=0;} //primo costruttore punto(int a, int b) {x=a; y=b;} //secondo costruttore punto& MuoviPunto(int d1, int d2) {x+=d1; y+=d2; return *this; };

//ritorna l'oggetto stesso punto& Stampa(){cout << " punto= " << x << ", " << y << endl; return *this;}

};main(){

punto p1; // crea un'istanza della classe punto e salva il suo indirizzo // nella variabile this=&p1// attiva il costruttore di default: punto(&p1).// Il costruttore viene implicitamente tradotto come // punto(punto *const this) {this -> x=0; this->y=0;};

punto p2(1,1); //attiva il secondo costruttore: punto(&p2, 1, 1), e modifica in //punto(punto *const this,int a,int b){this->x=a; this->y=b; return;}

p2.MuoviPunto(2, 2).Stampa(); //diventa possibile l'associazione a sinistrap1.Stampa().MuoviPunto(1,1).Stampa();

}Output: punto= 3, 3 punto= 0, 0 punto= 1, 1

Page 53: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

53

• Altro esempio di autoriferimento: concatenazione di stringhe

#include <iostream.h>//oop27.cppclass stringa{

int len; //dati privatichar *str;

public: //definizione dei metodistringa(int=0);stringa(const char *);stringa &concat(const stringa&);char *visualizza();

};//in questo modo è possibile scrivere:main(){

stringa a(80);stringa b("sequenza");stringa c(" di questa");stringa d(" prova");

 a=b.concat(c).concat(d);cout << a.visualizza();

}

Page 54: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

54

//implementazione dei metodistringa::stringa(int n){ len=n; if(n>0){ str=new char (len+1); str[0]='\0'; } }

stringa::stringa(const char *s){ len=strlen(s); str=new char[len+1]; strcpy(str,s); }

char* stringa::visualizza(){ return str; }

stringa& stringa::concat(const stringa &s){

len += s.len;char *temp=new char[len+1];strcpy(temp,str);strcat(temp, s.str); //temp="sequenza di questa"str=temp; //str e' la stringa dell'oggetto che ha attivato concatreturn *this; //ritorna l'oggetto che ha attivato concat

} Output:sequenza di questa prova

Page 55: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

55

Array di oggetti• definizione:

contatore c1, c2[100];c2[10].stampa();

• il costruttore e il distruttore vengono chiamati per ciascun elemento dell'array• per un vettore di oggetti appartenenti ad una classe con un costruttore, la classe

deve avere un costruttore senza argomenti

#include <stdio.h>//oop28.cppclass punto{

int x1, x2;public: punto(int x, int y) {x1=x; x2=y;} punto(){x1=0; x2=0;} void visualizza(){printf("x1, y1 ",x1, x2);}

};main(){

punto a(1,2);punto va[20];for(int i=1;i<20;i++) va[i].visualizza();

}

 

Page 56: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

56

Lo specificatore friend• aggiunta all’incapsulamento e mascheramento. Ma: cautela!• normalmente: solo un insieme ben definito di messaggi può essere inviato ad

un'oggetto di una classe che deve avere i metodi sufficienti per elaborare i dati• 'friend' specifica quali classi esterne possono accedere ai componenti privati//oop29.cpp Esempio: la classe B accede direttamente ai dati privati della classe A#include <iostream.h>class A{ friend class B; //indicazione unidirezionale!! int uno, due, tre; public:

A(){uno=0; due=0; tre=30;}; void inc(){uno++;due++;}; void lst(){cout<<"A::uno="<<uno<<" A::due="<<due<<" A::tre="<<tre<<endl; }};class B{ int uno, due; public:

B(){uno=10;due=20;}; void dec(){uno--; due--;};

void lst(A &a){cout<<"B::uno="<<uno<<" B::due="<<due<<" A::tre="<<a.tre<< endl;};};main(){

A a,b; B c,d; a.lst(); c.lst(a);}

Page 57: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

57

Elementi statici di una classe

• un elemento dichiarato static, viene condiviso in un'unica copia da tutti i oggetti della classe (normalmente ogni oggetto ha i propri dati!)

• esempio: per conoscere quanti oggetti di una classe sono stati definiti:

#include <iostream.h>//oop30.cppclass punto{

int x,y;public:

static int n_punti; punto(){n_punti++;};

};int punto::n_punti=0;main(){

punto a, b, c; cout << "nr oggetti:" << punto::n_punti << endl;}

• poiché l’elemeto statico è comune tutti gli oggetti, una modifica in un punto modifica tutti gli altri

Page 58: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

58

Inizializzazione di oggetti• Problema: string nome(“Luigi”); nuovo=nome;

• Inizializzazione memberwise• Costruttore memberwise: nomeclasse::nomeclasse(const nomeclasse&);

//oop31.cpp

#include <iostream.h>

class stringa

{

int len;

char *ch;

public:

stringa(){len=0;} //costruttore di default

stringa(const char *s) //costruttore con argomenti; s e' puntatore a stringa costante

{

len=strlen(s); ch=new char[len+1]; strcpy(ch,s);

}

stringa(const stringa&s) //costruttore di copia memberwise

{

len=s.len; ch=s.ch;

}

void list(){cout<<ch<<endl;}

};

main()

{

stringa a, b("Luigi");

stringa c=b; //l’oggetto c viene definito e inizializzato con l’oggetto b

c.list();

}

Page 59: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

59

• uso della inizializzazione memberwise:• oggetto1=oggetto2• passaggio argomenti per copia alle funzioni:

Class stringa

{

public:

//…

int val(){return len;}

};

int lung(stringa s){return s.val();}

main()

{

stringa a, b("Luigi"), c=b;

c.list();

cout << lung(c);}

• ritorno per valore di un oggetto:stringa crea(int l)

{

stringa s;

//...

return s; //usa l’iniz. di copia

}

• modalita’ per riferimento: non richiede copia locale!

Page 60: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

60

#include <iostream.h> //oop32.cpp Esempio di costruttori per copiaclass stringa{

int len; char *ch; public: stringa() {cout << "costruttore di default" << endl; len=0;}//costruttore di default stringa(const char *s) //costruttore con argomenti; s e' puntatore a stringa costante

{ cout << "costr. con argomenti" << endl; len=strlen(s); ch=new char[len+1]; strcpy(ch,s);}

stringa(const stringa&s) //costruttore di copia { cout << "costruttore di copia" << endl; len=s.len; ch=s.ch;}

void list(){cout<<ch<<endl;} int val(){return len;} void set(int n){len=n;}

void setp(char *ps){ch=ps;}};int lung(stringa s){return s.val();} //usa l'inizializzazione di copiastringa crea(int l){ stringa s; char *ps; s.set(l); ps=new char[l+1]; s.setp(ps); return s;} //usa l’iniz. di copia}main(){

stringa a; //costruttore di default stringa b("Luigi"); //costruttore con argomenti stringa c=b; //inizializzazione di copia c.list(); cout << lung(c); a=crea(10); cout << lung(a);}Output:costruttore di defaultCostr. con argomenticostruttore di copiaLuigicostruttore di copia5costruttore di defaultcostruttore di copiacostruttore di copia10

Page 61: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

61

Overloading degli operatori 

• ridefinizione di simboli del linguaggio• notazione infissa anche fra tipi diversi• limiti:

• solo operatori gia’ definiti• l’operatore che viene ridefinito conserva le sue caratteristiche di associativita’, precedenza e numero di

argomenti• almeno uno degli argomenti deve essere di tipo classe• non si possono usare operatori che non hanno significato in C (es. **)

• Specificatore: operator <operatore da sovrapporre>• operatori binari (+,-,*,/) e unari (++, --, +=, etc)• operatore binario: definito da un metodo interno con un argomento - a.add(b) – oppure

con due argomenti – a=a.add(a,b) - classe C { priv;

... public: C binary_op(C); C binary_op(C, C); } classe binary_op(classe arg){return classe(priv+arg.priv);}

classe binary_op(classe arg1, classe arg2){ return classe(arg1.priv+arg2.priv);} main(){

a.binary_op(b);a=a.binary_op(a,b);

}

Page 62: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

62

• operatore unario: metodo intero ad una classe senza argomenti operatore unario U: l'espressione argomento U oppure U argomento può essere:

• argomento.U() oppure U(argomento)

• non è possibile realizzare applicazione prefissa e postfissa

/* Uso degli operatori unari e binari */

//oop33.cpp

#include <iostream.h>

void main()

{

int a=1;

int b;

cout << "prima a= " << a << '\n';

b = a++; // l'operatore post-incremento e' unario: prima assegna e poi incrementa

cout << "dopo a++: a= " << a << " b=" << b <<'\n';

a=1;

b = ++a; /* l'operatore pre-incremento e' unario: prima incrementa e poi assegna*/

cout << "dopo ++a: a= " << a << " b=" << b <<'\n';

a=1;

b = a+1; /* l'operatore somma e' binario: prima somma e poi assegna */

cout << "dopo a+1: a= " << a << " b=" << b <<'\n';

}

Page 63: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

63

• overloading di operatori unari

#include <iostream.h>//oop34.cppclass contatore{

unsigned int valore; public: contatore(){valore=0;} void operator++(){if(valore<65535) valore++;}//overloading di ++ void operator--(){if(valore>0) valore--;}//overloading di () void operator()(unsigned int n){if((valore>=0)&&(valore<65535)) valore=n;} unsigned int val(){return valore;}};

main(){

contatore c1,c2;c2(10);

for(short i=0; i<10; i++){ c1++; c2++; } cout << "valore finale di c1=" << c1.val() << " finale di c2=" << c2.val();}

Output:Valore finale di c1=10 finale di c2=20

Page 64: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

64

• numeri complessi//oop35.cpp#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>class complesso{

private: float pr, pi;

public: complesso(){pr=0;pi=0;} //costruttore di default complesso(float x,float y); //altro costruttore void cadd(complesso arg); //operazione binaria void csub(complesso arg); //operazione binaria

void cmult(complesso arg);void visualizza();

};// definizione funzionicomplesso::complesso(float x, float y){ pr=x; pi=y; }void complesso::cadd(complesso arg){ pr+=arg.pr; pi+=arg.pi; }void complesso::csub(complesso arg){ pr-=arg.pr; pi-=arg.pi; }void complesso::cmult(complesso arg){ float temp1, temp2;

temp1=pr*arg.pr - pi*arg.pi; temp2=pr*arg.pi + pi*arg.pr; pr=temp1; pi=temp2; }

Page 65: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

65

void complesso::visualizza(){

if(pi<0)cout << '\n' << "complesso: " << pr << "- j" << abs(pi);

elsecout << '\n' << "complesso: " << pr << "+ j" << pi;

}main(){

complesso a(1,3), b(2,2); a.visualizza(); b.visualizza();

a.cadd(b); b.cadd(b); a.visualizza(); b.visualizza(); a.csub(b); a.visualizza(); b.visualizza(); a.cmult(b); a.visualizza(); b.visualizza();}

Output:complesso: 1+ j3complesso: 2+ j2complesso: 3+ j5complesso: 4+ j4complesso: -1+ j1complesso: 4+ j4complesso: -8+ j0complesso: 4+ j4

Page 66: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

66

• seconda versione//oop36.cpp#include <iostream.h>#include <math.h>class complesso{

private: float pr, pi; public: complesso(){pr=0;pi=0;} //costruttore di default complesso(float x,float y); //altro costruttore complesso cadd(complesso arg); complesso csub(complesso arg);

complesso cmult(complesso arg);void visualizza();

};complesso::complesso(float x, float y){ pr=x; pi=y; }complesso complesso::cadd(complesso arg){complesso t; t.pr=pr+arg.pr;

t.pi=pi+arg.pi; return t;}complesso complesso::csub(complesso arg){complesso t; t.pr=pr-arg.pr; t.pi=pi-

arg.pi; return t;}complesso complesso::cmult(complesso arg) { complesso t; float temp1, temp2;

temp1=pr*arg.pr - pi*arg.pi; temp2=pr*arg.pi + pi*arg.pr; t.pr=temp1; t.pi=temp2; return t;

}

Page 67: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

67

void complesso::visualizza()

{

if(pi<0)

cout << '\n' << "complesso: " << pr << "- j" << abs(pi);

else

cout << '\n' << "complesso: " << pr << "+ j" << pi;

}

main()

{

complesso a(1,3), b(2,2); a.visualizza(); b.visualizza();

a=a.cadd(b); b=b.cadd(b); a.visualizza(); b.visualizza();

a=a.csub(b); a.visualizza(); b.visualizza();

a=a.cmult(b); a.visualizza(); b.visualizza();

}

Page 68: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

68

• overloading degli operatori//oop37.cpp#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>class complesso{

private: float pr, pi; public: complesso(){pr=0;pi=0;} //costruttore di default complesso(float x,float y); //altro costruttore complesso operator+(complesso arg); complesso operator-(complesso arg);

complesso operator*(complesso arg);complesso operator*(float arg);void visualizza();

};// definizione funzionicomplesso::complesso(float x, float y){ pr=x; pi=y; }complesso complesso::operator+(complesso arg) //complesso operator+

(complesso b){ co{ complesso t; t.pr=pr+arg.pr; t.pi=pi+arg.pi; return t;}complesso complesso::operator-(complesso arg){ complesso t; t.pr=pr-arg.pr; t.pi=pi-arg.pi; return t;}

Page 69: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

69

complesso complesso::operator*(complesso arg){ complesso t; float temp1, temp2;

temp1=pr*arg.pr - pi*arg.pi; temp2=pr*arg.pi + pi*arg.pr; t.pr=temp1; t.pi=temp2; return t;

}complesso complesso::operator*(float arg){ //prodotto con tipo diverso!

return complesso(arg*pr, arg*pi);}void complesso::visualizza(){

if(pi<0)cout << '\n' << "complesso: " << pr << "- j" << abs(pi);

elsecout << '\n' << "complesso: " << pr << "+ j" << pi;

}main(){

complesso a(1,3), b(2,2), c, d; a.visualizza(); b.visualizza();

a=a+b; b=b+b; a.visualizza(); b.visualizza(); a=a-b; a.visualizza(); b.visualizza(); a=a*b; a.visualizza(); b.visualizza();

a=a*2; //attenzione: non e’ possibile 2*a!a.visualizza(); c=a+a; a=((a+b-c)*c)*2; a.visualizza();

}

Page 70: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

70

Libreria <stream.h>

• la classe ostream è definita in stream.h: l'operatore<< viene sovrapposto per

gestire l'output di tutti i tipi predefiniti o definita dell'utente. Semplificando:

class ostream

{

private:

...

public:

ostream & operator << (char *ch);

ostream & operator << (int i);

ostream & operator << (long l);

...

};

• l’operazione cout << i puo’ essere vista come cout.operator<<(i)• l’operazione cout << i << j; puo’ essere vista come

cout.operator<<(i).operator<<(j)

Page 71: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

71

Template di classi: classi generiche       il concetto di template -modello- e’ stato introdotto per creare classi generiche//oop38.cpp#include <iostream.h>/* implementazione in C++ del tipo di dato astratto STACK tramite array di interi */class stack {private:

int *bottom; // puntatore al fondo dello stackint *top; // puntatore alla cima dello stack

public:stack() // costruttore della classe stack{ bottom = top = new int[100]; }~stack() // distruttore della classe stack{ delete bottom; }void push (int c){ if ( (top -bottom) < 100 ) *top++ = c; }int pop(){ if ( --top >= bottom ) return *top; else return -1;}

}; // end class stack

void main(){

stack s;int i;

for (i = 0; i < 10; i++) s.push(i);for (i = 0; i < 10; i++) cout << s.pop();

}

Page 72: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

72

• Problema della classe stack: cambiamento di tipo://oop39.cpp#include <iostream.h>/* implementazione in C++ del tipo di dato astratto STACK tramite array di interi */class stack {private:

double *bottom; // puntatore al fondo dello stackdouble *top; // puntatore alla cima dello stack

public:stack() // costruttore della classe stack{ bottom = top = new double[100]; }~stack() // distruttore della classe stack{ delete bottom; }void push (double d){ if ( (top -bottom) < 100 ) *top++ = d; }double pop(){

if ( --top >= bottom )return *top;

else return -1;

}}; // end class stackvoid main(){

stack s;

for (short i = 0; i < 10; i++) s.push(i*3.14);for (short i = 0; i < 10; i++) cout << s.pop() << ' ';

}

Page 73: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

73

//oop40.cpp#include <iostream.h>/* tipo di dato astratto STACK di interi e double con TEMPLATE */template<class tipo>class stack {private:

tipo *bottom; // puntatore al fondo dello stacktipo *top; // puntatore alla cima dello stack

public:stack() // costruttore della classe stack{ bottom = top = new tipo[100]; }~stack() // distruttore della classe stack{ delete bottom; }void push (tipo d){ if ( (top -bottom) < 100 ) *top++ = d; }tipo pop(){ if ( --top >= bottom ) return *top;

else return -1;}

}; // end class stackvoid main(){

stack<int> s1; stack<double> s2;

for (short i = 0; i < 10; i++) s1.push(i);for (short i = 0; i < 10; i++) s2.push(i*3.14);cout << "stack di interi: ";for (short i = 0; i < 10; i++) cout << s1.pop() << ' ';cout << "\nstack di double: ";

for (short i = 0; i < 10; i++) cout << s2.pop() << ' ';}

Page 74: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

74

Derivazione di classi 

• l'ereditarietà permette ai programmatori di riutilizzare una classe esistente per costruire una gerarchia di componenti software riutilizzabile

• personalizzazione della classe d'origine• Basi della ereditarietà: la classe derivata; ogni OOP gestisce in modo diverso i

dettagli• in C++:

• la classe derivata eredita/modifica tutti i metodi propri della classe d'origine aggiungendo metodi nuovi

• gestisce una gerarchia di classi• derivazione singola una classe può avere un'unica classe d'origine (albero)• derivazione multipla una classe puo’ avere piu’ classi d’origine• visibilità dei dati privati della classe d'origine:• una classe derivata NON può accedere ai dati privati a meno che non sia autorizzata

farlo con lo specificatore friend o con la modalità protetta (più usata)• ogni oggetto di classe derivata ha i propri dati privati e una propria copia di dati

privati della classe d'origine

• sintassi:class ClasseDerivata: ClasseOrigine{...};

Page 75: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

75

• come viene realizzato il processo di ereditarietà?• Controllo accesso: indicatori “public”, “private”, “protected” • se l'indicatore viene omesso private• public: mantiene pubblico, privato, protected nella classe derivata ogni

componente rispettivamente pubblico, privato, protected della classe base

• se la classe base eredita componenti protetti privati li mantiene protetti o privaticlass Base{

int a; // privato nella classe baseprotected: //protetto: int bb;public: //pubblico int b;

};class Derivata: public Base{ int c; //privato nella classe

derivatapublic: int d; //pubblico int funz(){c=b+bb+d; return c;}

}main(){ Derivata x;

x.d=10;x.b=20;printf(x.funz());

// x.a, x.c non sono accessibili

Page 76: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

76

//oop41.cpp#include <iostream.h>class Persona{

protected: int eta; char *nome; public: Persona(const char *n, int e){ nome=new char[strlen(n)+1]; strcpy(nome,n); eta=e; } void presentati(){ cout << "sono una persona, mi chiamo " << nome << "ed ho " << eta <<

"anni" << endl; }};class Studente:public Persona{

private: int anno; char *facolta; public: Studente(char *n, char *f, int e, int a):Persona(n,e){ facolta=new char[strlen(f)+1]; strcpy(facolta,f); anno=a; } void presentati(){ cout<<"sono uno studente di nome "<<nome<<" ho "<<eta<<"anni e sono

iscritto a "<<facolta<<" al "<<anno<<" anno di corso" << endl; }};

Page 77: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

77

main()

{

Persona mario("Mario Verdi", 22);

Studente luigi("Luigi Rossi", "ingegneria", 24, 5);

mario.presentati();

luigi.presentati();

}sono una persona, mi chiamo Mario Verdi ed ho 22anni

sono uno studente di nome Luigi Rossi ho 24 anni e sono iscritto a ingegneria al 5 anno

di corso

• Tutti i metodi della classe d’origine possone essere inviati come messaggio agli oggetti della classe derivata

Page 78: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

78

Costruttori/distruttore nelle classi derivate

• legato alla visibilità tra oggetti derivati e oggetti base• se un oggetto di classe derivata viene inizializzato, il costruttore deve

assicurarsi che venga eseguita una inizializzazione anche dell'oggetto della classe di base-interna alla classe derivata-.

• il costruttore della classe derivata attiva uno dei costruttore della classe base: class Base{

int a;protected:

int bb;public:

int b;void Base(){a=0;}

}class Derivata:public Base{

int c;public: Derivata():Base(){c=0;}int funz(){c=c+bb+b+d; return c;}

}class Derivata2: public Derivata(){... public: derivata2():

Derivata()} 

Page 79: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

79

//ESEMPIO DI CLASSE BASE//file complesso.hclass complesso {

protected: float pr, pi; public: complesso(){pr=0;pi=0;} //costruttore di default complesso(float x,float y); //altro costruttore

void add(complesso arg); void sub(complesso arg);

void mpy(complesso arg);void visualizza();

};

// definizione funzionicomplesso::complesso(float x, float y){ pr=x; pi=y; }void complesso::add(complesso arg) //complesso operator+(complesso b){ co{ pr=pr+arg.pr; pi=pi+arg.pi; }void complesso::sub(complesso arg){ pr=pr-arg.pr; pi=pi-arg.pi; }void complesso::mpy(complesso arg){

float temp1, temp2;temp1=pr*arg.pr - pi*arg.pi; temp2=pr*arg.pi + pi*arg.pr; pr=temp1; pi=temp2;

}void complesso::visualizza(){ if(pi<0) cout << '\n' << "pr,pi " << pr << "- j" << abs(pi); else cout << '\n' << "pr,pi " << pr << "+ j" << pi; }

Page 80: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

80

//OOP42.cpp#include <iostream.h>#include <stdlib.h>#include <math.h>#include "complesso.h"class comp:public complesso{

private: float modulo; //valori trigonometrici float fase; public: comp(float x, float y):complesso(x, y) //costruttore { modulo=sqrt(x*x+y*y); fase=atan(y/x); }

void c2t() { float x=pr; float y=pi; modulo=sqrt(x*x+y*y); fase=atan(y/x); }

void t2c() { pr=modulo*cos(fase); pi=modulo*sin(fase); } void mult(comp arg) { modulo=modulo*arg.modulo; fase=fase+arg.fase; }

void div(comp arg) { modulo=modulo/arg.modulo; fase=fase-arg.fase; } void visualizza() { complesso::visualizza(); cout << " modulo=" << modulo << " fase=" << fase;}};main(){

comp a(1,1); comp b(1,2); a.visualizza(); b.visualizza(); a.mult(b); a.t2c(); a.visualizza(); a.div(b); a.t2c(); a.visualizza();}

Page 81: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

81

//oop43.cpp//derivazione#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>

class complesso{

protected: float pr, pi; public: complesso(float x,float y); //altro costruttore complesso cadd(complesso arg); complesso csub(complesso arg);

void visualizza();};// definizione funzionicomplesso::complesso(float x, float y){

pr=x; pi=y;}

complesso complesso::cadd(complesso arg){

pr+=arg.pr; pi+=arg.pi;}

Page 82: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

82

complesso complesso::csub(complesso arg){

pr-=arg.pr; pi-=arg.pi;}

void complesso::visualizza(){

cout << '\n' << "complesso: " << pr << "+ j" << pi;}

class comp: public complesso //derivazione per estendere la classe{

public: comp(float x, float y):complesso(x, y){};//costruttore comp cmult(comp arg); comp cdiv(comp arg); void visualizza(char a);};//comp comp::cmult(comp arg){

float temp1, temp2;

temp1=pr*arg.pr - pi*arg.pi; temp2=pr*arg.pi + pi*arg.pr; pr=temp1; pi=temp2;}

Page 83: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

83

comp comp::cdiv(comp arg){

float temp, temp1, temp2;

temp=arg.pr*arg.pr + arg.pi*arg.pi; temp1 = (pr*arg.pr + pi*arg.pi)/temp; temp2 = (pr*arg.pi - pi*arg.pr)/temp; pr=temp1; pi=temp2;}void comp::visualizza(char a){

cout << '\n' << a; complesso::visualizza();}

main(){

comp a(1,2), b(2,2); a.complesso::visualizza(); b.complesso::visualizza();

a.cadd(b); b.cadd(b); a.visualizza('a'); b.visualizza('b'); a.csub(b); a.visualizza('a'); b.visualizza('b'); a.cmult(b); a.visualizza('a'); b.cdiv(b); b.visualizza('b');}

Page 84: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

84

//OOP44.cpp liste derivate#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <string.h>#include <alloc.h>class nodo{

protected: nodo *next;

int valore; public: nodo(){next=NULL;valore=0;} void loadpun(nodo *a){next=a;} nodo *getpun(){return next;} void loadval(int a){valore=a;} int getval(){return valore;}};class nodo_ext: public nodo{ protected:

char *nome; int flag; public: nodo_ext(char *n, int f):nodo(){strcpy(nome,n);flag=f;} nodo_ext():nodo(){flag=0;nome="";} void loadnome(char *n){nome=new char[strlen(n)+1]; strcpy(nome,n);} char *getnome(){return nome;} void loadflag(int a){flag=a;} int getflag(){return flag;}};

Page 85: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

85

class lista{

private: nodo_ext *head; public:

lista(){head=NULL;} //costruttore void add(int val, char *n, int f); //at the bottom int tremove(); //toglie dalla coda e restituisce il nome void type(); //visita dalla cima e stampa il contenuto};void lista::add(int val, char *n, int f){

nodo_ext *temp, *prec;

if(head){ temp=head; while(temp){ prec=temp; temp=(nodo_ext *)temp->getpun(); } prec->loadpun(new nodo_ext); prec=(nodo_ext*)prec->getpun(); prec->loadval(val); prec->loadflag(f); prec->loadnome(n); prec->loadpun(NULL); } else { head=new nodo_ext; head -> loadval(val);

head -> loadflag(f); head -> loadnome(n); head -> loadpun(NULL); }}

Page 86: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

86

int lista::tremove(){

int n; nodo_ext *temp, *prec; temp=head;

if(head){ while(temp->getpun()) { prec=temp; yemp=(nodo_ext*)temp->getpun(); } n=temp->getval(); prec->loadpun(NULL); delete(temp);

return(n); } else return(65536); //65536 means empty}

void lista::type(){ nodo_ext *temp;

temp=head; while(temp){ cout << "val=" << temp->getval() << " nome=" << temp->getnome() << " flag="

cout << temp->getflag() << '\n'; temp=(nodo_ext*)temp->getpun(); }}main(){ lista L1, L2; int n;

for(int i=0;i<5;i++) L1.add(i,"primo",0); L1.type();

cout << "inizio a rimuovere dalla coda" << '\n'; while((n=L1.tremove())!=65536) cout << "remove L1 " << n << '\n';}

Page 87: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

87

• Regole di visibilita’: Classe base (superclasse) classe derivata (sottoclasse)

• Ricerca di una componente interna ad una variabile di sottoclasse:• Prima nella sottoclasse• Poi nelle componenti ereditate

• Funzioni ridefinite nella sottoclasse:nasconde la funzione della superclasseTutte le funzioni sono ancora attive! Si possono chiamare o con casting –((superclasse)oggetto sottoclasse).funzione – o con scope – Oggetto_sottoclasse.superclasse::funzione

• Riprendiamo la classe Studente. l’abbinamento funzione-oggetto e’ fatto STATICAMENTE dal compilatore (all’atto della compilazione) sulla base di tipo oggetto e argomenti

• Ma: con i puntatori?Studente *giorgio; Persona *giulio;

giorgio=new Studente(“Giorgio Bianchi", "ingegneria", 23,4); giorgio -> presentati();

• Attenzione: i puntatori possono puntare a oggetti diversi! giorgio -> presentati();

giulio=giorgio; giulio->presentati(); // la associazione e’ fatta sulla base del // tipo del puntatore e non dell’oggetto!!

• giulio e’ una persona ma punta ad uno studente!delete giulio cancella solo la persona: spreco spazio

• Funzioni virtuali: associazione sulla base del tipo di oggetto

Page 88: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

88

//oop45.cpp#include <iostream.h>class Persona{

protected: int eta; char *nome; public: Persona(const char *n, int e){ nome=new char[strlen(n)+1]; strcpy(nome,n); eta=e;} virtual void presentati() { cout << "sono una persona, mi chiamo " << nome << " ed ho " << eta << " anni“

<< endl; }};class Studente:public Persona{

private: int anno; char *facolta; public: Studente(char *n, char *f, int e, int a):Persona(n,e) { facolta=new char[strlen(f)+1]; strcpy(facolta,f); anno=a; } virtual void presentati(){ cout<<"sono uno studente di nome "<<nome<<" ho "<<eta<<" anni e sono iscritto a

"<<facolta<<" al "<<anno<<" anno di corso" << endl; }};

Page 89: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

89

main()

{

Persona mario("Mario Verdi", 22);

Studente luigi("Luigi Rossi", "ingegneria", 24, 5);

mario.presentati();

luigi.presentati();

Studente *giorgio; Persona *giulio;

giorgio=new Studente("Giorgio Bianchi", "ingegneria", 23,4);

giorgio -> presentati();

giulio=giorgio; giulio->presentati();

}

Output con funzioni virtuali:

sono una persona, mi chiamo Mario Verdi ed ho 22 anni

sono uno studente di nome Luigi Rossi ho 24 anni e sono iscritto a ingegneria al 5 anno di corso

sono uno studente di nome Giorgio Bianchi ho 23 anni e sono iscritto a ingegneria al 4 anno di corso

sono uno studente di nome Giorgio Bianchi ho 23 anni e sono iscritto a ingegneria al 4 anno di corsOutput o

Output senza funzioni virtuali

sono una persona, mi chiamo Mario Verdi ed ho 22anni

sono uno studente di nome Luigi Rossi ho 24 anni e sono iscritto a ingegneria al 5 anno di corso

sono uno studente di nome Giorgio Bianchi ho 23 anni e sono iscritto a ingegneria al 4 anno di corso

sono una persona, mi chiamo Giorgio Bianchi ed ho 23anni

Page 90: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

90

Polimorfismo e funzioni virtuali

• Polimorfismo: capacità di rispondere in modo differenziato agli stessi comandi

realizzato con overloading delle funzioni e con le funzioni virtuali• overloading delle funzioni: la scelta della funzione da attivare è effettuata

esaminando una lista degli operandi o il tipo di oggetti tramite cui vengono operate le richieste alle operazioni

• abbinamento statico(static binding): deciso alla compilazione• abbinamento dinamico(dynamic binding): deciso in run-time

• overloading quando gli oggetti vengono rappresentati con puntatore:• i puntatori possono puntare a oggetti di tipo diverso!• ma l'abbinamento statico si basa sul tipo di puntatore e non sul tipo di oggetto

puntato!• funzione virtuale: funzione il cui abbinamento con l'oggetto è fatto in run-time

sintassi: virtual int funz(){..........} 

Page 91: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

91

• una funzione definita virtuale nella classe base in una gerarchia di derivazione, rende virtuali tutte le funzioni con stesso prototipo e componenti la classe derivata

•  l'abbinamento dinamico oggetto-funzione con le funzioni virtuali funziona solo se gli oggetti sono gestiti con puntatore. Se l'oggetto gestito con il nome, l'associazione e' statica.

• tre casi in cui la chiamata di una funzione virtuale è risolta staticamente:• quando la chiamata e’ effettuata con un oggetto e non con un puntatore• quando si usa scope (::) alla classe nella chiamata con puntatore• quando una funzione virtuale è chiamata all'interno di costruttore o

distruttore

 • costruttori e distruttori virtuali

• Un costruttore non puo’ essere mai dichiarato virtuale (deve essere dichiarato prima)

• Distruttori possono essere virtuali!

Page 92: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

92

//oop46.cpp#include <iostream.h>class SuperficiePiana{ protected: float dim1; public: SuperficiePiana(float d) {dim1=d;} virtual void presentati() { cout << “Sono una superficie piana, la mia prima dimensione e' " << dim1 ; } virtual float Area(){ return 0;}};class triangolo: public SuperficiePiana{ private: float dim2; public: triangolo(float d1, float d2) : SuperficiePiana(d1) { dim2=d2; } virtual void presentati() { cout<<“Sono un triangolo di dimensioni " << dim1 <<" e " << dim2 ; } virtual float Area(){ return dim1*dim2/2.; }};class cerchio: public SuperficiePiana{ public: cerchio(float d1):SuperficiePiana(d1) {} virtual void presentati() { cout<< “Sono un cerchio" ; } virtual float Area(){ return 3.14 * dim1*dim1; }};

Page 93: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

93

main(){

SuperficiePiana * f1;

f1=new SuperficiePiana(2.); f1->presentati(); cout << ". La mia area = " << f1->Area() << endl;

f1=new triangolo(2.,4.); f1->presentati(); cout << ". La mia area = " << f1->Area() << endl;

}

Altra possibilita’:...stampa_info(SuperficiePiana *s){ s->presentati(); cout << “ La mia area=" << s->Area() << endl;}main(){ SuperficiePiana f1(2); triangolo f2(3,4); cerchio f3(1);

stampa_info(&f1); stampa_info(&f2); stampa_info(&f3);}

Page 94: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

94

//oop47.cpp// aggiunta della classe trapezioclass trapezio:public SuperficiePiana{ private: float dim2; float dim3; public: trapezio(float d1, float d2, float d3):SuperficiePiana(d1) {dim2=d2;dim3=d3;} void presentati() { cout << "sono un trapezio con basi=" << dim1 << ", " << dim2 <<

" e altezza= " << dim3 ; } float Area(){return (dim1+dim2)*dim3/2; }};

main(){ SuperficiePiana f1(2); triangolo f2(3,4); cerchio f3(1); trapezio f4(2,3,4);

stampa_info(&f1); stampa_info(&f2); stampa_info(&f3); stampa_info(&f4);

}

Page 95: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

95

Polimorfismo al lavoro

• I vantaggi del polimorfismo• Esempio: creazione di una ADT lista per realizzare un censimento

(categorie di persone, dati sulle persone etc..)• Esempio di lista senza polimorfismo senza istruzione friend• Esempio di lista senza polimorfismo con istruzione friend• Esempio di modifica della lista lista senza polimorfismo e con istruzione

friend

• Esempio di lista polimorfica con istruzione friend• Esempio di modifica della lista polimorfica

Page 96: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

96

• Lista non polimorfica senza costrutto friend: header file//lista2.h#include <iostream.h>enum tipo_nodo{studente,lavoratore, pensionato} ;struct tipo_studente{ int matricola; int anno_di_corso;};class nodo{ private: char cognome[10]; char nome[10]; int anni; int codice_fiscale; tipo_nodo attivita; union {tipo_studente s; float stipendio; int anni_quiescenza;}; nodo *next; public: nodo(char *co, char *no, int a, int cf, tipo_nodo t); nodo();

void set_attivita(tipo_nodo t); void set_cognome(char *c); void set_nome(char *n);

void set_anni(int a); void set_cf(int cf); void set_matricola(int m); void set_anno_corso(int ac); void set_stipendio(float s); void set_quiescenza(int q); void set_next(nodo * t);

Page 97: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

97

tipo_nodo get_attivita();

char * get_cognome();

char * get_nome();

int get_anni();

int get_cf();

int get_matricola();

int get_anno_corso();

float get_stipendio();

int get_quiescenza();

nodo * get_next();

};

class lista

{

private:

nodo *radice;

public:

lista();

void insert(nodo *n);

void remove(char *c);

void stampa();

};

//fine header file lista2.h

Page 98: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

98

//oop48.cpp. Implementazione dei metodi lista non polimorfica, senza friend

#include <iostream.h>

#include "lista2.h"

//implementazione dei costruttori

nodo::nodo(char *co, char *no, int a, int cf, tipo_nodo t)

{ strcpy(cognome,co); strcpy(nome,no); anni=a; codice_fiscale=cf; attivita=t; next=0; }

nodo::nodo()

{ strcpy(cognome,"\0"); strcpy(nome,"\0"); anni=0; codice_fiscale=0; next=0; }

//implementazione dei metodi di nodo

void nodo::set_attivita(tipo_nodo t) { attivita=t; }

void nodo::set_cognome(char *c){ strcpy(cognome,c); }

void nodo::set_nome(char *n) { strcpy(nome,n); }

void nodo::set_anni(int a) { anni=a; }

void nodo::set_cf(int cf) { codice_fiscale=cf; }

void nodo::set_matricola(int m) { s.matricola=m; }

void nodo::set_anno_corso(int ac) { s.anno_di_corso=ac; }

void nodo::set_stipendio(float s) { stipendio=s; }

void nodo::set_quiescenza(int q) { anni_quiescenza=q;}

void nodo::set_next(nodo * t) { next=t;}

tipo_nodo nodo::get_attivita() { return attivita; }

char * nodo::get_cognome() { return cognome; }

char * nodo::get_nome() { return nome; }

int nodo::get_anni() { return anni; }

int nodo::get_cf() { return codice_fiscale; }

int nodo::get_matricola() { return s.matricola; }

int nodo::get_anno_corso() { return s.anno_di_corso; }

float nodo::get_stipendio() { return stipendio; }

int nodo::get_quiescenza() { return anni_quiescenza;}

nodo * nodo::get_next() { return next; }

Page 99: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

99

//oop48.cpp (continuazione).

lista::lista() //implementazione del costruttore di lista

{ radice=0; }

void lista::insert(nodo *n) //implementazione dei metodi di lista

{

nodo *nuovo, *p, *q;

nuovo=new nodo(n->get_cognome(),n->get_nome(),n->get_anni(),n->get_cf(),n->get_attivita());

switch(nuovo->get_attivita())

{

case studente:

nuovo->set_matricola(n->get_matricola()); nuovo->set_anno_corso(n->get_anno_corso());

break;

case lavoratore:

nuovo->set_stipendio(n->get_stipendio());

break;

case pensionato:

nuovo->set_quiescenza(n->get_quiescenza());

break;

}

nuovo->set_next(0);

p=q=radice;

if(p==0) {p=radice=nuovo;}

else { while(p!=0)

{q=p; p=p->get_next();}

q->set_next(nuovo);

}

}

void lista::remove(char *c) {}

//remove non implementata in questa versione per semplicita’

Page 100: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

100

//oop48.cpp (continuazione).

void lista::stampa()

{

nodo *p;

p=radice;

while(p!=0)

{

cout<<p->get_cognome()<<" "<<p->get_nome()<<" anni "<<p->get_anni()<<" CF "<<p->get_cf()<< " ";

switch (p->get_attivita())

{

case studente:

cout << "studente ";

cout<<"matricola n."<<p->get_matricola()<<"anno di corso "<<p->get_anno_corso() << endl;

break;

case lavoratore:

cout << "lavoratore "; cout << "stipendio:"<<p->get_stipendio() << endl;

break;

case pensionato:

cout << "pensionato "; cout << "anni di quiescenza" << p->get_quiescenza() << endl;

}

p=p->get_next();

}

}

Page 101: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

101

//oop48.cpp (continuazione e main). main(){ //vari modi di creare l'oggetto nodo. 1. mediante il costruttore con argomenti

lista l; nodo t("Teseo","Giovanni",70,1234,pensionato); t.set_quiescenza(5); l.insert(&t); //2. mediante i metodi per modificare i campi privati t.set_cognome("Terreni"); t.set_nome("Piero"); t.set_attivita(studente); t.set_anni(30); t.set_cf(2222); t.set_matricola(230); t.set_anno_corso(5); l.insert(&t);//3.mediante puntatori e lo statement new

nodo *t1; t1=new nodo("Pallino", "Pinco", 23, 3333, lavoratore); t1->set_stipendio(1000); l.insert(t1); t1=new nodo("Tizio", "Gianni", 33, 3222, lavoratore); t1->set_stipendio(1500); l.insert(t1);

l.stampa();}

OutputTeseo Giovanni anni 70 CF 1234 pensionato anni di quiescenza5Terreni Piero anni 30 CF 2222 studente matricola n.230anno di corso 5Pallino Pinco anni 23 CF 3333 lavoratore stipendio:1000Tizio Gianni anni 33 CF 3222 lavoratore stipendio:1500

Page 102: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

102

//lista1.h//lista non polimorfica con uso dello statement FRIEND. Header file:#include <iostream.h>enum tipo_nodo{studente,lavoratore, pensionato} ;struct tipo_studente{ int matricola; int anno_di_corso;};class nodo{ friend class lista; private: char cognome[10]; char nome[10]; int anni; int codice_fiscale; tipo_nodo

attivita; union {tipo_studente s; float stipendio; int anni_quiescenza;}; nodo *next;

public: nodo(char *co, char *no, int a, int cf, tipo_nodo t); nodo();

void set_attivita(tipo_nodo t); void set_cognome(char *c); void set_nome(char *n);

void set_anni(int a); void set_cf(int cf); void set_matricola(int m); void set_anno_corso(int ac); void set_stipendio(float s); void set_quiescenza(int q);};class lista{ private:

nodo *radice;public:

lista();void insert(nodo *n);

void remove(char *c); void stampa();};

Page 103: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

103

//oop49.cpp implementazioni dei metodi della lista non polimorfica.#include <iostream.h>#include "lista1.h"nodo::nodo(char *co, char *no, int a, int cf, tipo_nodo t){ strcpy(cognome,co); strcpy(nome,no); anni=a; codice_fiscale=cf; attivita=t; next=0; nodo::nodo(){ strcpy(cognome,"\0"); strcpy(nome,"\0"); anni=0; codice_fiscale=0; next=0; }void nodo::set_attivita(tipo_nodo t) { attivita=t; }void nodo::set_cognome(char *c) { strcpy(cognome,c); }void nodo::set_nome(char *n) { strcpy(nome,n); }void nodo::set_anni(int a) { anni=a; }void nodo::set_cf(int cf) { codice_fiscale=cf; }void nodo::set_matricola(int m) { s.matricola=m; }void nodo::set_anno_corso(int ac) { s.anno_di_corso=ac; }void nodo::set_stipendio(float s) { stipendio=s; }void nodo::set_quiescenza(int q) { anni_quiescenza=q;}lista::lista() { radice=0; }void lista::insert(nodo *n){ nodo *nuovo, *p, *q; nuovo=new nodo( n->cognome, n->nome, n->anni, n->codice_fiscale, n->attivita ); switch(n->attivita) { case studente: nuovo->s.matricola=n->s.matricola; nuovo->s.anno_di_corso=n->s.anno_di_corso; break; case lavoratore: nuovo->stipendio=n->stipendio; break; case pensionato: nuovo->anni_quiescenza=n->anni_quiescenza; break; } nuovo->next=0; p=q=radice; if(p==0) {p=radice=nuovo;} else { while(p!=0){q=p; p=p->next;} q->next=nuovo; }}

Page 104: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

104

//oop49.cpp (continua) implementazioni dei metodi della lista non polimorfica.

void lista::remove(char *c)

{}

void lista::stampa()

{

nodo *p; p=radice;

while(p!=0)

{

cout<<p->cognome<<" "<<p->nome<<" anni "<<p->anni<<" CF "<<p->codice_fiscale<<" ";

switch (p->attivita)

{

case studente:

cout << "studente ";

cout<<"matricola n."<<p->s.matricola<<"anno di corso "<<p->s.anno_di_corso << endl;

break;

case lavoratore:

cout << "lavoratore con stipendio="<<p->stipendio << endl;

break;

case pensionato:

cout << "pensionato ";

cout << "anni di quiescenza" << p->anni_quiescenza << endl;

}

p=p->next;

}

}

Page 105: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

105

//oop49.cpp (continua) implementazioni del main della lista non polimorfica.

main()

{

lista l; nodo t;

t.set_cognome("Teseo"); t.set_nome("Giovanni"); t.set_attivita(pensionato);

t.set_anni(70); t.set_cf(1234); t.set_quiescenza(5);

l.insert(&t);

t.set_cognome("Pierucci"); t.set_nome("Piero"); t.set_attivita(lavoratore);

t.set_anni(40); t.set_cf(1111); t.set_stipendio(2000);

l.insert(&t);

t.set_cognome("Terreni"); t.set_nome("Piero"); t.set_attivita(studente);

t.set_anni(30); t.set_cf(2222); t.set_matricola(23); t.set_anno_corso(5);

l.insert(&t);

l.stampa();

}

Output

Teseo Giovanni anni 70 CF 1234 pensionato anni di quiescenza5

Pierucci Piero anni 40 CF 1111 lavoratore con stipendio=2000

Terreni Piero anni 30 CF 2222 studente matricola n.23anno di corso 5

Page 106: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

106

//inserimento nella lista di una categoria aggiuntiva. Lista non polimorfica con friend

// lista3.h

#include <iostream.h>

enum tipo_nodo{studente,lavoratore, pensionato, disoccupato} ; //modifica

struct tipo_studente{ int matricola; int anno_di_corso;};

struct disocc{ int mesi_disoccupazione; int nr_impieghi;}; //modifica

class nodo

{ friend class lista;

private:

char cognome[10]; char nome[10]; int anni; int codice_fiscale; tipo_nodo attivita;

union {tipo_studente s; float stipendio; int anni_quiescenza; disocc dis;}; // modifica

nodo *next;

public:

nodo(char *co, char *no, int a, int cf, tipo_nodo t); nodo(); ~nodo();

void set_attivita(tipo_nodo t); void set_cognome(char *c); void set_nome(char *n);

void set_anni(int a); void set_cf(int cf); void set_matricola(int m);

void set_anno_corso(int ac); void set_stipendio(float s); void set_quiescenza(int q);

void set_disoc(int d); void set_impie(int i);

};

class lista

{

private:

nodo *radice;

public:

lista(); ~lista(); void insert(nodo *n); void remove(char *c); void stampa();

};

Page 107: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

107

//oop50.cpp

//Modifica: inserimento di una categoria aggiuntiva. Implementazione metodi

//Lista non polimorfica con friend!

#include <iostream.h>

#include "lista3.h"

nodo::nodo(char *co, char *no, int a, int cf, tipo_nodo t)

{ strcpy(cognome,co); strcpy(nome,no); anni=a; codice_fiscale=cf; attivita=t; next=0; }

nodo::nodo()

{ strcpy(cognome,"\0"); strcpy(nome,"\0"); anni=0; codice_fiscale=0; next=0; }

nodo::~nodo(){};

void nodo::set_attivita(tipo_nodo t) { attivita=t; }

void nodo::set_cognome(char *c) { strcpy(cognome,c); }

void nodo::set_nome(char *n) { strcpy(nome,n); }

void nodo::set_anni(int a) { anni=a; }

void nodo::set_cf(int cf) { codice_fiscale=cf; }

void nodo::set_matricola(int m) { s.matricola=m; }

void nodo::set_anno_corso(int ac) { s.anno_di_corso=ac; }

void nodo::set_stipendio(float s) { stipendio=s; }

void nodo::set_quiescenza(int q) { anni_quiescenza=q;}

void nodo::set_disoc(int d) { dis.mesi_disoccupazione=d;}

void nodo::set_impie(int i) { dis.nr_impieghi=i;}

lista::lista()

{ radice=0; }

Page 108: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

108

// oop50.cpp (continua)

lista::~lista()

{ // questo e’ il metodo piu’ complesso. Quali sono i due metodi semplici?

nodo *p,*q;

do{

p=q=radice; while(p->next!=0){q=p;p=p->next;} q->next=0; delete p;

} while(q!=radice);

delete radice;

}

void lista::insert(nodo *n)

{

nodo *nuovo, *p, *q;

nuovo=new nodo( n->cognome, n->nome, n->anni, n->codice_fiscale, n->attivita );

switch(n->attivita)

{ case studente:

nuovo->s.matricola=n->s.matricola; nuovo->s.anno_di_corso=n->s.anno_di_corso; break;

case lavoratore: nuovo->stipendio=n->stipendio; break;

case pensionato: nuovo->anni_quiescenza=n->anni_quiescenza; break;

case disoccupato: //modifica

nuovo->dis.mesi_disoccupazione=n->dis.mesi_disoccupazione;

nuovo->dis.nr_impieghi=n->dis.nr_impieghi; break;

}

nuovo->next=0; p=q=radice;

if(p==0) {p=radice=nuovo;} else { while(p!=0){q=p; p=p->next;} q->next=nuovo; }

}

Page 109: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

109

// oop50.cpp (continua)

void lista::remove(char *c)

{// in questo esempio non e' stata scritta. Si lascia per esercizio }

void lista::stampa()

{

nodo *p;

p=radice;

while(p!=0)

{ cout<<p->cognome<<" "<<p->nome<<"\t anni "<<p->anni<<" CF "<<p->codice_fiscale<< " ";

switch (p->attivita)

{ case studente:

cout << "studente ";

cout<<"matricola nr."<<p->s.matricola<<" anno di corso "<<p->s.anno_di_corso << endl;

break;

case lavoratore:

cout << "lavoratore "; cout << "stipendio="<<p->stipendio << endl; break;

case pensionato:

cout << "pensionato ";

cout << "anni di quiescenza=" << p->anni_quiescenza << endl; break;

case disoccupato: //modifica

cout<<"disoccupato da ";

cout<<p->dis.mesi_disoccupazione<<" mesi. nr. impieghi="<<p->dis.nr_impieghi<<endl;

}

p=p->next;

}

}

Page 110: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

110

// oop50.cpp (continua)

main()

{

lista l;

nodo t1("Teseo", "Giovanni", 70, 1234, pensionato); t1.set_quiescenza(5);

l.insert(&t1);

nodo t2("Pierucci", "Piero", 40, 1111, lavoratore); t2.set_stipendio(2000);

l.insert(&t2);

nodo t3("Terreni", "Piero", 30, 2222, studente); t3.set_matricola(23);

t3.set_anno_corso(5);

l.insert(&t3);

nodo t4("Rossi", "Luigi", 25, 3276, disoccupato); t4.set_disoc(5); t4.set_impie(0);

l.insert(&t4);

l.stampa();

}

Output:

Teseo Giovanni anni 70 CF 1234 pensionato anni di quiescenza=5Pierucci Piero anni 40 CF 1111 lavoratore stipendio=2000Terreni Piero anni 30 CF 2222 studente matricola nr.23 anno di corso 5Rossi Luigi anni 25 CF 3276 disoccupato da 5 mesi. nr. impieghi=0

Page 111: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

111

//lista4.h

//lista polimorfica. Header file

#include <iostream.h>

class persona

{

friend class lista;

protected:

char cognome[10];

char nome[10];

int anni;

int codice_fiscale;

persona *ptr;

persona *next;

public:

persona(char *co, char *no, int a, int cf);

persona();

~persona();

void set_cognome(char *c);

void set_nome(char *n);

void set_anni(int a);

void set_cf(int cf);

virtual void stampa();

virtual void insert();

};

Page 112: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

112

//lista4.h (continua)

class studente:public persona

{

friend class lista;

private:

int matricola;

int anno_di_corso;

public:

studente(char *co, char *no, int a, int cf, int mat, int an):persona(co, no, a, cf)

{ matricola=mat; anno_di_corso=an; }

studente():persona()

{ matricola=0; anno_di_corso=0;}

void set_matricola(int m);

void set_anno_corso(int ac);

void stampa(); void insert();

};

class lavoratore:public persona

{ friend class lista;

private:

float stipendio;

public:

lavoratore(char *co, char *no, int a, int cf, float s):persona(co, no, a, cf){stipendio=s;}

lavoratore():persona() { stipendio=0;}

void set_stipendio(float s);

void stampa(); void insert();

};

Page 113: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

113

//lista4.h (continua)

class pensionato:public persona

{

friend class lista;

private:

int anni_quiescenza;

public:

pensionato(char *co, char *no, int a, int cf, int q):persona(co, no, a, cf)

{ anni_quiescenza=q; }

pensionato():persona()

{ anni_quiescenza=0;}

void set_quiescenza(int q);

void stampa();

void insert();

};

class lista

{

private:

persona *radice;

public:

lista();

~lista();

void inserisci(persona *n);

void rimuovi(char *c);

void stampa();

};

Page 114: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

114

//oop51.cpp. Lista polimorfica

//Implementazione dei metodi della lista polimorfica

#include <iostream.h>

#include "lista4.h"

persona::persona(char *co, char *no, int a, int cf)

{ strcpy(cognome,co); strcpy(nome,no);anni=a; codice_fiscale=cf; next=0; }

persona::persona()

{ strcpy(cognome,"\0"); strcpy(nome,"\0"); anni=0; codice_fiscale=0; next=0; }

persona::~persona(){};

void persona::set_cognome(char *c) { strcpy(cognome,c); }

void persona::set_nome(char *n) { strcpy(nome,n); }

void persona::set_anni(int a) { anni=a; }

void persona::set_cf(int cf) { codice_fiscale=cf; }

void persona::insert()

{ ptr=new persona(cognome, nome, anni, codice_fiscale); }

void persona::stampa()

{ cout << cognome << " " << nome << "\t anni " << anni << " CF= " << codice_fiscale ;}

void studente::set_matricola(int m) { matricola=m; }

void studente::set_anno_corso(int ac) { anno_di_corso=ac;}

void studente::stampa()

{ persona::stampa();

cout << " Studente, matricola=" << matricola << " anno di corso="<<anno_di_corso<<endl;

}

void studente::insert()

{ ptr=new studente(cognome, nome, anni, codice_fiscale, matricola, anno_di_corso); }

Page 115: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

115

//oop51.cpp. Lista polimorfica

void lavoratore::set_stipendio(float s)

{ stipendio=s; }

void lavoratore::stampa()

{ persona::stampa(); cout << " Lavoratore, stipendio=" << stipendio <<endl; }

void lavoratore::insert()

{ ptr=new lavoratore(cognome, nome, anni, codice_fiscale, stipendio); }

void pensionato::set_quiescenza(int q)

{ anni_quiescenza=q;}

void pensionato::stampa()

{ persona::stampa(); cout << " Pensionato, anni di quiescenza=" << anni_quiescenza <<endl;}

void pensionato::insert()

{ ptr=new pensionato(cognome, nome, anni, codice_fiscale, anni_quiescenza); }

lista::lista()

{ radice=0; }

lista::~lista()

{ // naturalmente per cancellare lo spazio degli oggetti bisogna avere una lista

// bidirezionale. Si lascia per esercizio

persona *p,*q;

do{ p=q=radice; while(p->next!=0){q=p;p=p->next;} q->next=0; delete p; } while(q!=radice);

delete radice;

}

Page 116: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

116

//oop51.cpp (continua). Lista polimorfica

void lista::inserisci(persona *n)

{

persona *p, *q;

p=q=radice; n->insert();

if(p==0) {p=radice=n->ptr;} else { while(p!=0){q=p; p=p->next;} q->next=n->ptr; }

}

void lista::rimuovi(char *c)

{// in questo esempio non e' stata scritta. Si lascia per esercizio }

void lista::stampa()

{

persona *p;

p=radice; while(p!=0) { p->stampa(); p=p->next; }

}

main()

{

lista l; persona t;

studente st("Terreni", "Piero", 30, 2222, 23, 5);

lavoratore la("Pierucci", "Piero", 40, 1111, 2000);

pensionato pen("Rossi", "Luigi", 70, 3276, 5);

l.inserisci(&st); l.inserisci(&la); l.inserisci(&pen);

l.stampa();

}

Page 117: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

117

//Introduzione di una classe aggiuntiva. Lista polimorfica. Header file

//lista5.h

#include <iostream.h>

class persona

{

friend class lista;

protected:

char cognome[10];char nome[10];int anni;int codice_fiscale;persona *ptr;persona *next;

public:

persona(char *co, char *no, int a, int cf);

persona(); ~persona();

void set_cognome(char *c); void set_nome(char *n); void set_anni(int a);

void set_cf(int cf);

virtual void stampa(); virtual void insert();

};

class studente:public persona

{

friend class lista;

private:

int matricola; int anno_di_corso;

public:

studente(char *co, char *no, int a, int cf, int mat, int an):persona(co, no, a, cf)

{ matricola=mat; anno_di_corso=an; }

studente():persona() { matricola=0; anno_di_corso=0;}

void set_matricola(int m); void set_anno_corso(int ac); void stampa(); void insert();

};

Page 118: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

118

//lista5.h (continua)

class lavoratore:public persona

{

friend class lista;

private:

float stipendio;

public:

lavoratore(char *co, char *no, int a, int cf, float s):persona(co, no, a, cf)

{ stipendio=s; }

lavoratore():persona() { stipendio=0;}

void set_stipendio(float s); void stampa(); void insert();

};

class pensionato:public persona

{

friend class lista;

private:

int anni_quiescenza;

public:

pensionato(char *co, char *no, int a, int cf, int q):persona(co, no, a, cf)

{ anni_quiescenza=q; }

pensionato():persona() { anni_quiescenza=0;}

void set_quiescenza(int q); void stampa(); void insert();

};

Page 119: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

119

//lista5.h (continua) Classe aggiunta nell’header file

class disoccupato:public persona

{

friend class lista;

private:

int mesi_disoccupazione;

int nr_impieghi;

public:

disoccupato(char *co, char *no, int a, int cf, int md, int ni):persona(co, no, a, cf)

{ mesi_disoccupazione=md; nr_impieghi=ni; }

disoccupato():persona() { mesi_disoccupazione=0; nr_impieghi=0; }

void set_disoccupazione(int md) { mesi_disoccupazione=md; }

void set_impieghi(int ni) { nr_impieghi=ni; }

void stampa() { persona::stampa(); cout << " Disoccupato da " << mesi_disoccupazione;

cout << " mesi. Nr. impieghi=" << nr_impieghi << endl; }

void insert()

{

ptr=new disoccupato(cognome,nome,anni,codice_fiscale,mesi_disoccupazione,nr_impieghi);

};

};

class lista

{ private:

persona *radice;

public:

lista(); ~lista(); void inserisci(persona *n); void rimuovi(char *c); void stampa();

};

Page 120: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

120

//oop52.cpp

//implementazione dei metodi della lista polimorfica

#include <iostream.h>

#include "lista5.h"

persona::persona(char *co, char *no, int a, int cf)

{ strcpy(cognome,co); strcpy(nome,no); anni=a; codice_fiscale=cf; next=0; }

persona::persona()

{ strcpy(cognome,"\0"); strcpy(nome,"\0"); anni=0; codice_fiscale=0; next=0; }

persona::~persona(){};

void persona::set_cognome(char *c) { strcpy(cognome,c); }

void persona::set_nome(char *n) { strcpy(nome,n); }

void persona::set_anni(int a) { anni=a; }

void persona::set_cf(int cf) { codice_fiscale=cf; }

void persona::insert() { ptr=new persona(cognome, nome, anni, codice_fiscale); }

void persona::stampa()

{ cout << cognome << " " << nome << "\t anni " << anni << " CF= " << codice_fiscale ;}

void studente::set_matricola(int m) { matricola=m; }

void studente::set_anno_corso(int ac) { anno_di_corso=ac;}

void studente::stampa()

{

persona::stampa();

cout << " Studente, matricola=" << matricola << " anno di corso="<<anno_di_corso<<endl;

}

void studente::insert()

{ ptr=new studente(cognome, nome, anni, codice_fiscale, matricola, anno_di_corso); }

Page 121: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

121

//oop52.cpp (continua)

void lavoratore::set_stipendio(float s) { stipendio=s; }

void lavoratore::stampa()

{ persona::stampa(); cout << " Lavoratore, stipendio=" << stipendio <<endl; }

void lavoratore::insert()

{ ptr=new lavoratore(cognome, nome, anni, codice_fiscale, stipendio); }

void pensionato::set_quiescenza(int q) { anni_quiescenza=q;}

void pensionato::stampa()

{ persona::stampa(); cout << " Pensionato, anni di quiescenza=" << anni_quiescenza <<endl;}

void pensionato::insert()

{ ptr=new pensionato(cognome, nome, anni, codice_fiscale, anni_quiescenza); }

lista::lista()

{ radice=0; }

lista::~lista()

{ // questa versione e’ la piu’ complessa possibile. Quali altre versioni semplici si possono utilizzare?

persona *p,*q;

do{ p=q=radice; while(p->next!=0){q=p;p=p->next;} q->next=0; delete p; } while(q!=radice);

delete radice;

}

void lista::inserisci(persona *n)

{ persona *p, *q;

p=q=radice; n->insert();

if(p==0) {p=radice=n->ptr;} else { while(p!=0){q=p; p=p->next;} q->next=n->ptr; }

}

void lista::rimuovi(char *c)

{// in questo esempio non e' stata scritta. Si lascia per esercizio }

Page 122: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

122

//oop52.cpp (continua)

void lista::stampa()

{

persona *p;

p=radice;

while(p!=0)

{

p->stampa(); p=p->next;

}

}

main()

{

lista l; persona t;

studente st("Terreni", "Piero", 25, 2222, 23, 5);

lavoratore la("Pierucci", "Piero", 40, 1111, 2000);

pensionato pen("Rossi", "Luigi", 70, 3276, 5);

disoccupato dis("Ferri", "Luigi", 40, 2323, 8, 1);

l.inserisci(&st);

l.inserisci(&la);

l.inserisci(&pen);

l.inserisci(&dis);

l.stampa();

}

Page 123: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

123

Vantaggi del polimorfismo

• Permette di scrivere codice generico che si adatta automaticamente alle specializzazioni future

• Permette di creare nuovi metodi senza cambiare il resto del codice• Semplice estensione del codice pre-esistente riutilizzabilita’ del codice• Attenzione: se l’impostazione e’ corretta, si puo’ cambiare molto

lavorando poco…• …se si modifica troppo il codice originale, l’impostazione e’ sbagliata!• Modifiche concentrate migliore manutenzione• Attenzione: i vantaggi si pagano con una certa perdita di efficienza!

Page 124: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

124

Derivazione multipla di classi

• Finora, le gerarchie di classi erano formate da una unica superclasse• Derivazione multipla: pluralita’ di superclassi

Es. superclasse Studente, superclasse Lavoratore sottoclasse Studente-Lavoratore che deriva da entrambe!

Inoltre: sia Studente che Lavoratore derivano da Persona• Quindi:

Persona/ \

Studente Lavoratore\ /

Studente-Lavoratore

• Sintassi:class Persona{ … }class Studente:public Persona{ … }class Lavoratore:public Persona{ … }class Studente_Lavoratore:public Studente, public Lavoratore{ … }

Page 125: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

125

//oop53.cpp derivazione multipla#include <iostream.h>class Persona{

protected: int eta; char *nome; public: Persona(const char *n, int e){ nome=new char[strlen(n)+1]; strcpy(nome,n); eta=e;} void presentati() { cout << "sono una persona, mi chiamo " << nome << " ed ho " << eta << "

anni" << endl; }};class Studente:public Persona{

private: int anno; char *facolta; public: Studente(char *n, char *f, int e, int a):Persona(n,e) { facolta=new char[strlen(f)+1]; strcpy(facolta,f); anno=a; } void presentati(){ cout<<"sono uno studente di nome "<<nome<<" ho "<<eta<<" anni e sono iscritto a

"<<facolta<<" al "<<anno<<" anno di corso" << endl; }};

Page 126: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

126

class Lavoratore:public Persona{

private: int impresa; float stipendio; public: Lavoratore(char *n, int e, int i, float s):Persona(n,e) { impresa=i;

stipendio=s; } void presentati(){ cout<<"sono un lavoratore di nome "<<nome<<" ed ho "<<eta<<" anni. Lavoro in

"<<impresa<<" e guadagno " << stipendio <<endl; }};class Stud_Lav:public Studente, public Lavoratore{

private: int corso_serale; public: Stud_Lav(char *n, int e, int i, float s, int a, char *f, int c): Studente(n, f, e, a),

Lavoratore(n, e, i, s) { corso_serale=c; }

void presentati() { cout <<"sono uno studente lavoratore, e sono al corso serale "<< corso_serale << endl; }};

Page 127: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

127

main(){

Persona mario("Mario Verdi", 22); Studente luigi("Luigi Rossi", "ingegneria", 24, 5);

mario.presentati(); luigi.presentati();

Studente *giorgio; Persona *giulio; giorgio=new Studente("Giorgio Bianchi", "ingegneria", 23,4); giorgio -> presentati();

giulio=giorgio; giulio->presentati();

Lavoratore antonio("Antonio Pierucci", 28, 5, 1.7); antonio.presentati();

Stud_Lav piero("Piero Pieri", 28, 6, 1.7, 1, "ingegneria", 1); piero.presentati();}

Output

sono una persona, mi chiamo Mario Verdi ed ho 22 annisono uno studente di nome Luigi Rossi ho 24 anni e sono iscritto a ingegneria al 5 anno di corsosono uno studente di nome Giorgio Bianchi ho 23 anni e sono iscritto a ingegneria al 4 anno di corsosono una persona, mi chiamo Giorgio Bianchi ed ho 23 annisono un lavoratore di nome Antonio Pierucci ed ho 28 anni. Lavoro in 5 e guadagno 1.7sono uno studente lavoratore, e sono al corso serale 1

Page 128: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

128

Intermezzo

• Una riflessione sulla programmazione:

La programmazione e’ una attivita’ bizzarra:

Consiste nel costruire oggetti astratti

Sempre piene di difetti

Che costano molto

Sono testi con migliaia di frasi

Scritte da gente particolare

Per macchine molto stupide ma precise

E che cambiano di continuo …

Page 129: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

129

Terza parte:Programmazione ad oggetti in

Java

Page 130: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

130

Cos’è Java

• Linguaggio di programmazione definito dalla Sun• Obiettivo: sviluppo di applicazioni sicure, efficienti, robuste, su

piattaforme multiple, in reti eterogenee e distribuite• Linguaggio semplice e orientato agli oggetti• Interpretato: produce codice intermedio (“byte-code”) per una

“Java Virtual machine”:

• Portabile su diverse piattaforme• Architetturalmente neutro:

– Byte-code indipendente dalla architettura hardware– Il byte-code puo’ eseguire su un sistema che abbia un ambiente run-

time Java

• Robustezza: controlli estesi in compilazione e run-time

Codice sorgente compilatore Byte code Interprete

Page 131: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

131

Il byte-code

Method void main(java.lang.String[]) 0 iconst_0 // push costante 0 1 istore_2 // memorizza in var.locale 2 (a) 2 iconst_0 // push costante 0 3 istore_1 // memorizza in var.locale 1 (i) 4 goto 14 // vai alla riga 14 7 iload_2 // prendi a (push) 8 iload_1 // prendi i (push) 9 iadd // a+i 10 istore_2 // a = a+i 11 iinc 1 1 // i=i+1 14 iload_1 // prendi i (push) 15 iconst_5 // push costante 5 16 if_icmplt 7 // salta a 7 se i<5 19 return // esci

Sorgente in Java{

int i;int a;a=0;for(i=0;i<5;i++){ a += i; }

}Traduzione in byte-code:

Page 132: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

132

Cos’è Java (cont.)

• Distribuito:– Pensato per essere eseguito in rete– Funzioni di rete di basso e alto livello– Rete accessibile come i file locali

• Sicurezza:– Alcune caratteristiche del byte-code sono verificate prima della

interpretazione – salta molti controlli fatti normalmente a run-time efficienza– Indirizzamenti controllati dall’interprete

• Possibilita’ di caricamento dinamico delle classi dalla rete

• Concorrente (threaded)– Applicazioni concorrenti piu’ facili da scrivere– Migliore interazione

Page 133: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

133

Java e la rete

Sorgente Java

Compilatore

Byte-code

RETE

Carica le classi

Verifica e interpreta il byte-code

Ambiente di esecuzione

Network computing

Rete Calcolatore in reteProgrammi e dati

(non solo dati)

Page 134: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

134

Java White Paper (Sun, 1995)

• Primo scopo: eliminare la ridondanza del C e C++:– Caratteristiche sovrapposte, troppi modi per fare la stessa cosa– C++ aggiungendo classi a C, aumenta la ridondanza

• Principi guida di un buon linguaggio: semplicita’, unicita’, consistenza• Unicita’: fornire un buon modo per esprimere ogni operazione che interessa,

evitare che ce ne siano due• Altri linguaggi OO: Eiffel, Smalltalk, Ada• Applicazioni o Applets?

– Applet: codice creato per far parte di un documento– Applicazioni: compilatore scaricabile da rete (esempio, ftp.sun.com/pub)

• Alcuni strumenti Java:– javac <file.java> compila la classe in byte code– java <nome_della_classe_main> java virtual machine: interpreta byte

code– appletviewer <url|file> visualizza un applet– jdb <file[.class]> java debugger– javap <file[.class]> reverse eng., disassembla etc.

Page 135: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

135

// semplice esempio di programmazione C++ bubble sort

#include <stdio.h>

#include <iostream.h>

#include <stdlib.h>

#include <string.h>

struct sistema { float *aa; int ord; };

const int ord=10, ord1=3; // variabili non modificabili!

int bubble(float *, int N=ord);

void scambia(float &, float &); // passaggio per riferimento

void stampa(int); void stampa(float *a, int n=ord);

main()

{ sistema SS[ord1]; // definisce l'array SS di ord1 strutture 'sistema'

int nl;

for(short i=0;i<ord1;i++){ //carica le strutture

cout<<endl<<"carica"<<i; SS[i].ord=5+random(10); SS[i].aa = new float[SS[i].ord]; //alloca l'array in memoria libera

for(short j=0; j<SS[i].ord;j++) {SS[i].aa[j]=float(random(100)); cout<<SS[i].aa[j]<<" "; }

}

for(short i=0;i<ord1;i++){

printf("\n\nArray originale %d:\n", i); stampa(SS[i].aa,SS[i].ord); nl=bubble(SS[i].aa,SS[i].ord); //argomento di default

stampa(nl); //overloading di funzioni e valori default

stampa(SS[i].aa,SS[i].ord); //overloading di funzioni e valori default

}

}

Page 136: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

136

int bubble(float *A, int N)

{

char *flag="notsorted"; int nloop=0;

while(!strcmp(flag, "notsorted")){

flag="sorted"; nloop++;

for(short i=0;i<N-1;i++)

if(*(A+i) > *(A+i+1)){ //A[i] e' *(A+i)

scambia(*(A+i),*(A+i+1)); //passa per riferimento!!

flag="notsorted";

}

}

return nloop;

}

void scambia(float &a, float &b) // il compilatore passa l'indirizzo delle var.

{ float temp=a; a=b; b=temp; }

void stampa(int n)

{ printf("\nArray ordinato (nr. cicli=%d):\n", n); }

void stampa(float *a, int n)

{

for(short j=0;j<n;j++) cout << a[j] << " "; cout ; // definizione short

}

Page 137: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

137

//stesso esempio di programmazione C++ rimuovendo i puntatori espliciti

#include <stdio.h>

#include <iostream.h>

#include <stdlib.h>

#include <string.h>

struct sistema { float *aa; int ord; };

const int ord=10, ord1=3; // variabili non modificabili!

int bubble(float *, int N=ord); //argomento di default

void scambia(float *, int); // passaggio per riferimento

void stampa(int); void stampa(float *a, int n=ord);

main()

{ sistema SS[ord1]; // definisce l'array SS di ord1 strutture 'sistema'

int nl;

for(short i=0;i<ord1;i++){ //carica le strutture

cout<<endl<<"carica"<<i; SS[i].ord=5+random(10); SS[i].aa = new float[SS[i].ord];//alloca l'array nella memoria libera

for(short j=0; j<SS[i].ord;j++) {SS[i].aa[j]=float(random(100)); cout<<SS[i].aa[j]<<" "; }

}

for(short i=0;i<ord1;i++){

printf("\n\nArray originale %d:\n", i); stampa(SS[i].aa,SS[i].ord); nl=bubble(SS[i].aa,SS[i].ord); //argomento di default

stampa(nl); //overloading di funzioni e valori default

stampa(SS[i].aa,SS[i].ord); //overloading di funzioni e valori default

}

}

Page 138: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

138

int bubble(float A[], int N)

{

char *flag="notsorted";

int nloop=0;

while(!strcmp(flag, "notsorted")){

flag="sorted"; nloop++;

for(short i=0;i<N-1;i++)

if(A[i] > A[i+1]){

scambia(A,i);

flag="notsorted";

}

}

return nloop;

}

void scambia(float a[], int i) // il compilatore passa l'indirizzo delle var.

{ float temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; }

void stampa(int n)

{ printf("\nArray ordinato (nr. cicli=%d):\n", n); }

void stampa(float *a, int n)

{ for(short j=0;j<n;j++) cout << a[j] << " "; cout ; // definizione short }

Page 139: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

139

//stesso programma, sort, scritto in java

import java.io.*;

import java.util.Random;

class sort{

static int bubble(float A[], int N)

{

String flag="notsorted"; int nloop=0;

while(flag!="sorted"){

flag="sorted"; nloop++;

for(short i=0;i<N-1;i++)

if(A[i] > A[i+1]){

scambia(A,i);

flag="notsorted";

}

}

return nloop;

}

static void scambia(float a[], int i)

{

float temp=a[i];

a[i]=a[i+1]; a[i+1]=temp;

}

Page 140: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

140

static void stampa(int n)

{ System.out.print("Array ordinato (nr. cicli=" + n +")"); System.out.println(); }

static void stampa(float a[], int n)

{ for(short j=0;j<n;j++) System.out.print(a[j] + " "); System.out.println(); }

public static void main(String argv[])

{ int ord1=2; int ord[] = new int[ord1]; float SS[][] = new float[ord1][20];

int nl; Random r = new Random();

for(short i=0;i<ord1;i++){ //carica le strutture

System.out.println(); System.out.print("carica " + i +": ");

ord[i]=1+(int)(r.nextFloat()*10);

for(short j=0; j<ord[i];j++)

{SS[i][j]=(int)(r.nextFloat()*100); System.out.print(SS[i][j] + " ");} }

for(short i=0;i<ord1;i++){

System.out.print("\nArray originale " + i +"= "); System.out.println(); stampa(SS[i],ord[i]);

nl=bubble(SS[i],ord[i]); stampa(nl); stampa(SS[i],ord[i]);

}

} // fine del main

} //fine della classe

Page 141: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

141

Osservazioni

• Per gran parte e’ codice C++• Non ci sono variabili globali• Case sensitive• Un programma java e’ sempre un insieme di classi: nel programma, la classe

e’sort i cui metodi sono bubble, scambia, stampa, main• Il main e’ chiamato differentemente dal C++:

C++ Javavoid main(int argc, char * argv[]) public static main(String argv[])

Esempio:prog 5 argc=2, argv[0]=“prog”, argv[1]=5 argv[0]=5, argv.lenght=1

• L’input/optput e’ diverso dal C++: System.out(xx) = cout << xx• #include e’ sostituito da import: java.util.random e’ la classe Random dal

package util• Cosi’, Random r=new Random() crea una istanza della classe Random

e r.nextFloat() genera un numero random tra 0 e 1 attivando il metodo nextFloat• Assenza di struct e union in Java: in C++ e’ una parte dipendente dalla macchina

(allineamenti e dimensioni)

Page 142: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

142

Costanti, variabili, identificatori

• Non esiste ne’ #define ne’ const• Definizione di una costante:

final tipo_costante nome_costante = valore;

• Definizione di una variabile:

tipo_variabile nome_variabile [=valore][, nome_variabile [=valore]…]• Convenzioni per i nomi identificatori:

– Case misto per i nomi delle classi (es.: MiaClasse)

– I nomi delle costanti sono in lettere capitali (es.: PI_GRECO)

– Altri nomi (funzioni, variabili, parole riservate) sono in minuscolo o con case misto, partendo pero’ con una lettera minuscola

• Visibilita’ delle variabili: all’interno di un blocco { }. Se i blocchi sono annidati, non e’ possibile usare lo stesso nome

Page 143: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

143

Tipi di dati

• Tipi semplici: Interi, virgola mobile, caratteri, logici• Interi: tutti con segno (non esiste l’unsigned)

– Byte 8 bit con segno

– Short 16 bit con segno, big endian, high byte first

– Int 32 bit con segno

– Long 64 bit con segno

• Virgola mobile: formato IEEE-754– Float 32 bit

– Double 64 bit

• Caratteri:– Char 16 bit senza segno, codifica Unicode

• Logici:– Boolean due valori possibili, true e false

• Casting fra tipi primitivi, promozione automatica

Page 144: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

144

Casting

• Casting di tipi primitivi: – Perdita di precisione– Boolean non puo’ essere convertito in nessun tipo primitivo

• Casting di oggetti:– La classe di partenza e di arrivo devono essere in relazione ereditaria– Casting in superclasse fa’ perdere i dati della sottoclasse

• Casting tra tipi primitivi e oggetti:– Il package java.lang comprende classi speciali: Integer, Float, Boolean, …

per rappresentare oggetti equivalenti ai tipi primitiviInteger o = new Iteger(22); // tratta un valore come un oggetto

– Casting tra oggetti a dati primitivi: mediante metodi specialiInt n = o.intValue(); //restituisce 22

Page 145: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

145

Array

• Array o matrici: sono oggetti! Una variabile array punta a tutto l’oggetto. Campo dell’oggetto: length

• Array monodimensionali:

• int buf[]; esempio di dichiarazione di array di interi

• buf = new int[10]; esempio di allocazione

• String nome[]; esempio di dichiarazione di stringaclass buffer{

public static void main(String args[]) {

int buf[] = new int[10];//buf e’ un puntatore ad un oggetto array

float arr[] = new float[10];

buf[0]=1; int buf[] = new int[5]; // il vecchio array e’ eliminato (garbage)

arr[5] = 3.14; float[] new; //altro modo per dichiarare un array

new=arr; //arr e new puntano allo stesso oggetto array

System.out.println(“Valore di buf[0] = “ + buf[0]+”nr.elementi “+buf.length);

}

}

• Array multidimensionali:

• int buf[][] = new int[10][5]; //esempio di matrice di interi

Page 146: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

146

Array (cont.)

• I componenti di un array;

• Sono tutti dello stesso tipo

• Possono essere di tipo primitivo o riferimenti

• Sono indicizzati con int (controllo a run-time)

• Dichiarazione:

int[] a; oppure int a[];• Creazione:

a=new int[3];• Uso:

a[0]=1;• Array di array:

int a[][];

a=new int[3][2];• Array di oggetti:

class B{…} B a[]; a=new B[3];

Spazio dati: Spazio heap: a

a

null

1

a

Page 147: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

147

Packages

• Definizione di classi: simile a C++. Esistono classi predefinite, raggruppate in packages• Ogni classe va’ in un file separato: il nome del file sorgente deve essere esattamente

uguale al nome della classe, con estensione “.java”• La import (es. import java.io.*) importa tutte le classi di un package• Ogni programma inizia con import java.lang.*; (inserimento predefinito)• La import puo’ essere omessa, indicando esplicitamente quale classe si vuole utilizzare

esempio: import java.util.Random; Random r = new Random();oppure: java.util.Random r; r = new java.util.Random();

• Attenzione: la import non importa nulla. E’ solo una abbreviazione!• Il compilatore javac importa la classe quando richiesta, eventualmente compilando il

file .java.class Messaggi {

void msg1(){ System.out.println(“Primo messaggio”);void msg2(){System.out.println(“Secondo messaggio”);

}class Test {

public static void main(String[] args){Messaggi m1 = new Messaggi; Messaggi m2 = new Messaggi;m1.msg1(); m2.msg2()

}

• Le due classi vanno in due file, chiamati Messaggi.java e Test.java. Basta scrivere: javac test.java

Page 148: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

148

Puntatori• Gli oggetti in Java possono solo essere acceduti tramite puntatori

• Una variabile puo’ contenere valori primitivi o riferimento a oggetti

• Una variabile non puo’ contenere un oggetto

• Non esistono gli operatori “*”, “&”, “->” ma solo l’operatore punto “.”

• I membri della classe sono per default friend di altre classi del package

Esempio C++ Esempio Java#include <iostream.h>#include <math.h>class punto {

friend class stampa;float x, y; //privatepublic: punto(float a, float b){x=a; y=b;};

float distanza(punto *a){ float t=pow(x-a->x,2)+pow(y-a->y,2); return sqrt(t); }};class stampa{

public: void out(float a, float b, float c, float d) {

punto *p,*q=new punto(a,b), *r; cout << q->x << " " << q->y << endl;

p->x=c; p->y=d; cout << p->x << " " << p->y << endl;

cout << q->distanza(p); }};main(){ stampa s;

s.out(1,2,5,5); }

import java.io.*;class dots{ //file dots.java static void out(float a, float b, float c, float d) { punto p=new punto(0,0),q=new punto(a,b), r;

System.out.println(q.x +" "+ q.y); p.x=c; p.y=d;

System.out.println(p.x + " " + p.y); System.out.println("distanza="+ q.distanza(p)); }

public static void main(String argv[]) { out(1,2,5,5); System.exit(0); }}

class punto { //file punto.java float x, y; punto(float a, float b){x=a; y=b;}; float distanza(punto a){ float t=(float)(Math.pow(x-a.x,2)+Math.pow(y-a.y,2)); return (float)Math.sqrt(t); }};

Page 149: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

149

Garbage collection

• Come in C++, un oggetto e’ creato con new• Delete in C++ puo’ introdurre errori: cancellazione prematura,

cancellazione tardiva

• In Java non esiste l’operatore delete• Cancellazione automatica di oggetti quando non ci sono piu’ riferimenti ad

essi

Page 150: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

150

Incapsulamento

• Membri privati: accesso consentito solo dall’interno dei metodi della classe

• Membri protetti: accesso consentito alla classe e alle classi derivate• Membri pubblici: accesso consentitoa qualsiasi funzione• Sintassi C++ Sintassi Java

class Mia{ class Mia{Private: private int i;

int i; public int j;

double d; private double d;

Public: public void funzione() {…}

int j; }

void funzione() { … }

}

• Di default, i membri sono visibili pubblicamente• Membri statici: esiste solo una copia condivisa da tutte le instanze

Page 151: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

151

//file Veicolo.javaclass Veicolo{

private int VelocitaMassima;private int NumeroPosti;public Veicolo(int VM, int NP) // costruttore{ VelocitaMassima = VM; NumeroPosti = NP; }

}

//file mioveicolo.javapublic class mioveicolo{

public static void main(String args[]){

Veicolo MiaMacchina= new Veicolo(150, 5);System.out.println("Creato un oggetto di classe Veicolo");

}}

Page 152: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

152

//file Veicolo.javaclass Veicolo{

private int VelocitaMassima; // variabili privateprivate int NumeroPosti; // semantica per valorepublic Veicolo(int VM, int NP) // costruttore{ VelocitaMassima = VM; NumeroPosti = NP; }public int getVelocitaMax() // metodi pubblici{ return VelocitaMassima; }public int getNumeroPosti(){ return NumeroPosti; }

}

//file mioveicolo2.javapublic class mioveicolo2{

public static void main(String args[]){

int Intero;Veicolo MiaMacchina = new Veicolo(150, 5);System.out.print("La mia macchina ha ");System.out.print(MiaMacchina.getNumeroPosti()+" posti");System.out.print(" e raggiunge la velocita' di ");System.out.println(MiaMacchina.getVelocitaMax() + " km/h.");// Intero = MiaMacchina.NumeroPosti;// il compilatore da' errore

}}

Page 153: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

153

Stringhe

• Il tipo String crea un array di char• L’operatore + e’ sovrapposto per introdurre la concatenazione• La concatenazione puoì essere fatta con qualsiasi cosa: conversione

automatica in stringa• Operazioni piu’ comuni (String s=“blabla”)

– s.charAt(n) ritorna il carattere alla posizione n della stringa s

– s.substring(n) ritorna la sottostringa di s dalla posizione n alla fine

– s.compareTo(str) <, >, == 0 se “s” precede, segue, e’ uguale a “str”

– s.indexOf(‘c’) ritorna il primo indice del carattere ‘c’ in “s”

– s.lastIndexOf(‘c’) ritorna l’ultimo indice del carattere ‘c’ in “s”

– s.endsWith(“str”) ritorna vero o falso

Page 154: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

154

Costruttori e sovrapposizione

• I costruttori in Java hanno lo stesso significato del C++• Differenza: () anche se non ho argomenti • Differenza: i costruttori devono essere scritti in linea• Sovrapposizione (overloading): piu’ costruttori, con diversi argomenti

class punto { //file punto.java

float x, y;

punto(float a, float b){ x=a; y=b; //stesso che this.x=a; this.y=b;};

punto(float a){ x=a; y=0; };

punto(){ x=0; y=0; };

};

import java.io.*;

class dots{ //file dots.java

public static void main(String argv[]) {

punto p1=new punto(1,2);

punto p2=new punto; //errore

punto p3=new punto();

System.exit(0);

}

}

Page 155: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

155

Ereditarieta’

• Due tipi di ereditarieta’: di metodo e di interfaccia

• Ereditarieta’ di metodo:– eredità singola, parola chiave: extends

– L’istruzione super fa’ riferimento alla classe del padre)

– La classe figlia eredita:

• variabili e metodi della classe padre definiti public

• variabili e metodi della classe padre definiti protected

• variabili e metodi della classe padre senza attributo se appartiene allo stesso package

• variabili e metodi che la classe padre ha ereditato dagli «avi» della gerarchia

– Riutilizzare componenti già definiti, specializzandoli

class Base{ // superclasse

void fz1(){…}

void fz2(){…}

};

Class Derivata extends Base{ //sottoclasse di Base

void fz2(){…} //sostituisce fx2() di Base (overriding)

void fz3(){ //la classe Derivata ha tre metodi, fz1, fz2, f3

super.fz2(); //si riferisce al padre!

...

}

};

• Ereditarieta’ di interfaccia– eredità multipla, parola chiave: implements

Page 156: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

156

//file Veicolo.javaclass Veicolo //uguale a quello precedente!{ … }

//file VeicoloTerrestre.javaclass VeicoloTerrestre extends Veicolo{ private int NumeroRuote;

public VeicoloTerrestre(int VM, int NP, int NR) // costruttore{ super(VM,NP); // chiama il costruttore del padre

NumeroRuote = NR;}public int getNumeroRuote(){ return NumeroRuote; }

}//file VeicoloMarino.javaclass VeicoloMarino extends Veicolo{ private long Stazza;

public VeicoloMarino(int VM, int NP, long S){ super(VM,NP); Stazza = S; }public long getStazza(){ return Stazza; }

}//file mioveicolo3.javapublic class mioveicolo3{

public static void main(String args[]){

VeicoloTerrestre MiaMacchina = new VeicoloTerrestre(100, 5, 4); VeicoloMarino MiaNavenew VeicoloMarino(5, 10, 10);System.out.print("La mia macchina ha ");

System.out.print(MiaMacchina.getNumeroPosti() + " posti, ");System.out.println(MiaMacchina.getNumeroRuote() + " ruote");

System.out.println(" e una velocita' di "+MiaMacchina.getVelocitaMax()+"KM/h"); System.out.print("La mia nave ha ");

System.out.print(MiaNave.getNumeroPosti() + " posti, ");System.out.println("una stazza di " + MiaNave.getStazza());

System.out.println(" e una velocita' di "+MiaNave.getVelocitaMax()+"nodi/h");}

}

Page 157: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

157

Interfacce

• Interfaccia: struttura sintattica con nome• Specifica i nomi, gli argomenti e i tipi di ritorno dei metodi di una classe non ancora

implementata

• Una interfaccia puo’ essere implementata da una o piu’ classi

• Una classe puo’ implementare piu’ di una interfaccia ereditarieta’ multiplaclass MiaClasse implements A,B{…}

interface Punto { punto(float a, float b); float distanza(punto a);}

class MioPunto implements Punto { float x, y; punto(float a, float b) ){x=a; y=b;}; float distanza(punto a) { float t=(float)(Math.pow(x-a.x,2)+Math.pow(y-a.y,2)); return (float)Math.sqrt(t);};class TuoPunto implements Punto { float x, y; punto(float a, float b) ){x=2*a; y=2*b;}; float distanza(punto a) { float t=(float)(Math.abs(x-a.x)+Math.abs(y-a.y)); return (float)Math.sqrt(t)}};

Page 158: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

158

Costruttori e sovrapposizione

• I costruttori in Java hanno lo stesso significato del C++• Differenza: () anche se non ho argomenti • Differenza: i costruttori devono essere scritti in linea• Sovrapposizione (overloading): piu’ costruttori, con diversi argomenti

class punto { //file punto.java

float x, y;

punto(float a, float b){ x=a; y=b; //stesso che this.x=a; this.y=b;};

punto(float a){ x=a; y=0; };

punto(){ x=0; y=0; };

};

import java.io.*;

class dots{ //file dots.java

public static void main(String argv[]) {

punto p1=new punto(1,2);

punto p2=new punto; //errore

punto p3=new punto();

System.exit(0);

}

}

Page 159: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

159

Eccezioni

• Java non crea core files• Errori di run-time fanno scattare una eccezione• Di default, una eccezione causa la terminazione di un programma• Le eccezioni possono essere catturate con le istruzioni catch-try

try{...//istruzioni, chiamate a funzioni etc. da osservare

}catch(TipoDiEccezione e){ //cattura l’eccezione

...//descrive cosa fare quando

}

• Eccezioni built-in: ArithmeticException, NullPointerException, ClassCastException, IOException,

ArrayIndexOutOfBoundsException, NegativeArraySizeException, OutOfMemoryException, …

• Una eccezione e’ un oggetto, che viene ereditato da altri oggetti• L’istruzione catch cattura una eccezione e le sue derivate• Le eccezioni possono essere definite dall’utente con throw (lancia eccezioni)

– Definizione della classe NuovaEccezione

– throw new NuovaEccezione();

– try {…} catch (NuovaEccezione e) { … }

Page 160: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

160

Il tipo “Vector”

• Un Vector e’ un array dinamico• Gli elementi di un Vectorsono oggetti, non valori• La classe Vector e’ realizzata come un array ordinario

import java.util.*;

import java.io.*;

class vect{

public static void main(String argv[])

{

int n; Integer o;

Vector v=new Vector();

System.out.println("carico il Vector di interi");

for(int i=0; i<10; i++) v.addElement(new Integer(i*2));

System.out.println("visualizzo Vector:");

for(int i=0; i<10; i++) {

o=(Integer) v.elementAt(i);

n=(int)o.intValue();

System.out.println("elemento "+i+"="+n);

}

System.exit(0);

}

}

Page 161: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

161

public class ListNode {

public Object element ;

public ListNode next ;

/** Costruttore nodo isolato */

public ListNode ( Object element ) {

this( element, null ) ;

}

/** Costruttore nodo per liste unidirezionali, dove element e' non null */

public ListNode ( Object element, ListNode next ) {

if ( element == null )

throw new IllegalArgumentException ( ) ;

this.element = element ;

this.next = next ;

}

}

•Definizione di nodo per creare liste in Java

Page 162: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

162

Polimorfismo

• Gli oggetti della classe derivata hanno la stessa interfaccia della classe base, o un suo sovrainsieme

• Gli oggetti della classe derivata possono essere visti come oggetti ‘estesi’ della classe base

• Variabili del tipo della classe base possono contenere riferimenti a oggetti della classe derivata

• Quando viene inviato un messaggio a un oggetto, la scelta dell’implementazione del metodo è effettuata dinamicamente sulla base della classe effettiva, non del tipo della variabile (polimorfismo)

Page 163: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

163

//file Animale.java

public class Animale

{ public void verso()

{ System.out.println("Che animale sono?"); }

}

//file VersiAnimali.java

public class VersiAnimali

{ public static void main(String args[])

{ Animale t; Animale a=new Animale(); Animale b=new Cane(); Animale c=new Gatto();

t=a; t.verso();

t=b; t.verso();

t=c; t.verso();

}

}

//file Cane.java

public class Cane extends Animale

{ public void verso()

{ System.out.println("Sono un cane: Bau bau!"); }

}

//file Gatto.java

public class Gatto extends Animale

{ public void verso()

{ System.out.println("Sono un gatto: Miao!"); }

}

Page 164: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

164

//file PoliVeicolo.javaclass PoliVeicolo{ private int VelocitaMassima; private int NumeroPosti; public PoliVeicolo(int VM, int NP) { VelocitaMassima = VM; NumeroPosti = NP; }

public int getVelocitaMax() { return VelocitaMassima; }public int getNumeroPosti() { return NumeroPosti; }

public String stampa() {return "Veicolo con "+NumeroPosti+"posti e velocita' massima di“ +VelocitaMassima+"km/h"; };

}//file Ferrari.javaclass Ferrari extends PoliVeicolo{ public Ferrari(int VM, int NP) // costruttore

{ super(VM, NP); }public String stampa() //ridefinisce il metodo{ return "Sono una Ferrai, ho " + getNumeroPosti() + " posti"+

"e vado a” + getVelocitaMax()+"Km/h"; }}

//file Fiat500.javaclass Fiat500 extends PoliVeicolo{ public Fiat500(int VM,int NP) // costruttore

{ super(VM,NP); }public String stampa() //ridefinisce il metodo

{ return "Sono una Fiat500, ho " + getNumeroPosti() + " posti" + "e posso andare a”+getVelocitaMax()+"Km/h"; }

}

//file Veicoli.javapublic class Veicoli{ public static void main(String args[])

{ PoliVeicolo v=new PoliVeicolo(0,0); // istanza della classe padre Ferrari v1 = new Ferrari(300,1); Fiat500 v2 = new Fiat500(100,4);

System.out.println(v.stampa());v = v1; System.out.println(v.stampa()); v = v2; System.out.println(v.stampa());

}}

Page 165: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

165

Input/output in Java

• Flusso di dati sorgente-destinazione• Potenza della astrazione: sorgente/destinazione possono essere qualsiasi (file,

socket, tastiera, monitor etc)• In Java si legge e si scrive su un oggetto Stream• Classi del package java.io:

– Metodi di lettura: specificano come argomento la sorgente– Metodi di lettura: specificano come argomento la destinazione– Metodi di elaborazione: leggono i dati dal flusso indicato nel 1o argomento e

scrivono i dati elaborati sul 2o argomento

• I metodi di elaborazione non conoscono la sorgente o la distinazione: dettagli nascosti

• Gerarchia di classi:– Reader: input caratteri– Writer: output caratteri– InputStream: input byte– OutputStream: output byte– Buffered: associano un buffer allo stream di I-O. Il buffer:

• Permette di trasferire piu’ di un byte alla volta• Permette di inserire metodi di skip, mark e reset

Page 166: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

166

Input/output in Java• Legge dallo standard input e scrive sullo standard output

import java.io.*; //in questo caso considero le eccezionipublic class Copia1 { public static void main(String[] args) { BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

for(;;){ try{

String line=in.readLine(); System.out.println(line);

} catch(IOException e){ System.out.println("errore di IO : " + e);}}

}}

• Legge dallo standard input e scrive sullo standard output

import java.io.*; // in questo caso trascuro le eccezionipublic class Copia { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

for(;;){String line=in.readLine();

System.out.println(line);}

}}

Page 167: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

167

Input/output in Java

• Copia il file README nel file READout per interi

import java.io.*;

public class prova { public static void main(String[] args) throws IOException {

FileInputStream f = new FileInputStream("README"); FileOutputStream f1 = new FileOutputStream("READout");

while(f.available()!=0){int line=f.read();

f1.write(line);}

}}

Page 168: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

168

Input/output in Java

• La classe FILE: descrive le proprieta’ del file. Alcuni metodi compresi:

public java.lang.String getName();

public java.lang.String getPath();

public java.lang.String getAbsolutePath();

public java.lang.String getCanonicalPath();

public java.lang.String getParent();

public boolean exists();

public boolean canWrite();

public boolean canRead();

public boolean isFile();

public boolean isDirectory();

public long lastModified();

public long length();

public boolean mkdir();

public boolean renameTo(java.io.File);

public boolean mkdirs();

public java.lang.String list()[];

public boolean delete();

Page 169: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

169

Input/output in Java

• Esempio: lista di alcune caratteristiche del file README

import java.io.*;

public class prova1 {

public static void main(String[] args) throws IOException {

File f = new File("README");

System.out.println("Nome:" + f.getName());

System.out.println("Path:" + f.getPath());

System.out.println("Dimensione:" + f.length());

}

}

Page 170: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

170

Multithreading in Java

• Ogni thread e’ un oggetto, creato come istanza della classe java.lang.Thread• La classe Thread contiene tutti i metodi per gestire i threads• L’utente implementa il metodo run()• Uno dei metodi piu’ importanti e’ il metodo start() che lancia il thread

utilizzando il metodo run definito dall’utente• Ogni istanza di Thread deve quindi essere associata ad un metodo run• Ci sono due metodi per realizzare un thread:

– Implementando l’interfaccia Runnable– Estendendo la classe java.lang.Thread e sovrascrivendo il metodo run()

• Un thread termina quando – Finisce– Viene eseguito il metodo stop() del thread– Scatta una eccezione

• Lo scheduling e’ effettuato tramite le priorita’ (metodo setPriority())• A parita’ di priorita’ round-robin

Page 171: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

171

Multithreading in Java-metodo1-prima versione

import java.io.*;

public class PingPong{ //il main crea e lancia i thread

public static void main(String[] a){

Ping c=new Ping(); Pong t=new Pong();

Thread th1=new Thread(c); th1.start(); Thread th2=new Thread(t); th2.start();

}

}

class Ping implements Runnable{

public void run(){

while(true) {

try{ Thread.sleep(800); } catch(InterruptedException e) {}

System.out.println("Ping");

}

}

}

class Pong implements Runnable{

public void run(){

while(true) {

try{ Thread.sleep(990); } catch (InterruptedException e){}

System.out.println("\tPong");

}

}

}

Page 172: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

172

Multithreading in Java-metodo1-seconda versioneimport java.io.*;

public class PingPong1{ // file PingPong1.java

public static void main(String[] a){

Ping1 c=new Ping1(); Pong1 t=new Pong1();

}

}

class Ping1 implements Runnable{ //file Ping1.java. Ogni oggetto crea e lancia il proprio thread

Thread th;

public void run(){

while(true) {

try{ Thread.sleep(800); } catch(InterruptedException e) {}

System.out.println("Ping");

}

}

Ping1() {th=new Thread(this); th.start();}

}

class Pong1 implements Runnable{ //file Pong1.java

Thread th;

public void run(){

while(true) {

try{ Thread.sleep(990); } catch (InterruptedException e){}

System.out.println("\tPong");

}

}

Pong1(){ th=new Thread(this); th.start(); }

}

Page 173: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

173

Multithreading in Java-metodo2-prima versioneimport java.io.*;

public class PingPong2{ // il main crea e lancia i thread

public static void main(String[] a){

Ping2 c=new Ping2(); c.start(); Pong2 t=new Pong2(); t.start();

}

}

class Ping2 extends Thread{

public void run(){

while(true) {

try{ Thread.sleep(800); } catch(InterruptedException e) {}

System.out.println("Ping");

}

}

}

class Pong2 extends Thread{

public void run(){

while(true) {

try{ Thread.sleep(990); } catch (InterruptedException e){}

System.out.println("\tPong");

}

}

}

Page 174: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

174

Multithreading in Java-metodo2-seconda versioneimport java.io.*;

public class PingPong3{

public static void main(String[] a){

Ping3 c=new Ping3(); Pong3 t=new Pong3();

}

}

class Ping3 extends Thread{ //ogni thread si lancia da solo

public void run(){

while(true) {

try{ Thread.sleep(800); } catch(InterruptedException e) {}

System.out.println("Ping");

}

}

Ping3(){ start(); }

}

class Pong3 extends Thread{

public void run(){

while(true) {

try{ Thread.sleep(990); } catch (InterruptedException e){}

System.out.println("\tPong");

}

}

Pong3(){ start(); }

}

Page 175: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

175

In ogni caso, l’uscita è:

C:\jdk1.1.8\prove>java PingPong2

Ping

Pong

Ping

Pong

Ping

Pong

Ping

Pong

Ping

Ping

Pong

Ping

Ping

...

Page 176: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

176

Alcuni metodi di Thread

• public void start() //lancia il thread

• public void run() //esegue il codice

• public final void stop() //distrugge il thread

• public final void suspend() //sospende il thread

• public final void resume() //riattiva il thread

• public static void sleep(long n) //sospende il thread per n ms

• public final void setPriority(int priority) //modifica la //priorita’

• public final int getPriority() //ottiene la priorità corrente

• public static void yield() //rischedula

• public final native boolean isAlive() //esce con true se il//thread è vivo

• …

Page 177: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

177

Stati di un Thread

Newthread

RunnableNot

Runnable

Dead

new Thread()

start()

stop()

stop()run()exit stop()

yield()

suspend()sleep()wait()

resume()notify()

Page 178: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

178

Passaggio di parametri tra Thread

• Tutti i thread devono condividere un oggetto, che contiene i dati e i metodi• La condivisione viene effettuata mediante definizione del puntatore all’oggetto in ciascun

thread, e mediante l’inizializzazione del puntatore all’oggetto• L’oggetto in realta’ viene allocato nella classe principale (quella che contiene il main)• Esempio: due thread – pi e po – che si scambiano 5 reali, con ritardo (genera sequenaialita’

quindi in questo caso non ci sono problemi di mutua esclusione)public class pth{

public static void main(String[] a){ z buf=new z();

pi c=new pi(buf); po t=new po(buf);c.start(); t.start();

}}

• Definizione della classe z:import java.io.*;public class z{ float b[]= new float[10];

void put(int i, float f){ b[i]=f; }

float get(int i){ return(float)b[i]; }}

Page 179: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

179

Passaggio di parametri tra Thread

• Scrittura delle classi pi.java e po.javapublic class pi extends Thread{ z buf; pi(z buf){ this.buf=buf; }

public void run(){ while(true) { try{ Thread.sleep(800);} catch(InterruptedException e) {} System.out.print("leggo "); for (int i=0; i<5; i++) System.out.print(“ "+buf.get(i)); System.out.println(); }

}}

class po extends Thread{ z buf; Random r=new Random(); po(z buf){ this.buf=buf; }

public void run(){ while(true) {

try{ Thread.sleep(990);} catch (InterruptedException e){} System.out.print("\tscrivo "); for(int i=0; i<5; i++) { buf.put(i,r.nextFloat()); System.out.print(" "+buf.get(i)); } System.out.println(); }

}}

Page 180: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

180

Passaggio di parametri tra Thread

• In questo esempio si usano dei thread in Java che si scambiano dei dati mediante una classe condivisa, Buffer. La sincronizzazione e’ realizzata mediante algoritmo che attende se i puntatori di in e out sono coincidente.Attenzione: questa soluzione funziona solo con 1 produttore e 1 consumatore! Se ho piu’ produttori o piu’ consumatori, devo usare la mutua esclusione!

• Classe condivisa:

import java.io.*;public class Buffer{ private int buf[]= new int[10]; private int in, out; Buffer(){ in=0; out=0;} int get_in(){ return in; } int get_out(){ return out; } void put_in(int a){ in=a; } void put_out(int b){ out=b; } void put(int i, int f){ buf[i]=f; } int get(int i){ return (int)buf[i]; }}

Page 181: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

181

Passaggio di parametri tra Thread

• Produttore:public class Prod extends Thread{ // produttore Buffer buf; Random r; Prod(Buffer p){ this.buf=p; r=new Random(); }

public void run(){ int val; while(true) { val=r.nextInt(); while (buf.get_out()==((buf.get_in()+1)%10)); buf.put(buf.get_in(),val); System.out.println("\nproduco "+val+" in="+buf.get_in()); buf.put_in((buf.get_in()+1)%10); }

}}

• Consumatorepublic class Cons extends Thread{ // consumatore Buffer buf; Cons(Buffer p){ this.buf=p; }

public void run(){ int val; while(true) { while (buf.get_out()==buf.get_in()); val=buf.get(buf.get_out()); System.out.println("\nconsumo "+val+" out="+buf.get_out()); buf.put_out((buf.get_out()+1)%10); }

}}

Page 182: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

182

Passaggio di parametri tra Thread

• Altro consumatore

public class Cons1 extends Thread{ // consumatore Buffer buf; Cons1(Buffer p){ this.buf=p; }

public void run(){ int val; while(true) { while (buf.get_out()==buf.get_in()); val=buf.get(buf.get_out()); System.out.println("\ncons_1 "+val+“

out="+buf.get_out()); buf.put_out((buf.get_out()+1)%10); }

}}

• Programma principale:

public class pc{public static void main(String[] a){

Buffer buf=new Buffer();

Prod c=new Prod(buf); Cons t=new Cons(buf); Cons1 z=new Cons1(buf); c.start(); t.start(); z.start();

}}

Page 183: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

183

Passaggio di parametri e sincroniuzzazione tra Thread

• Una soluzione al problema e’ quello di usare un arbitro software. In questo caso si usa l’alternanza stretta. La classe condivisa e’ la seguente:

import java.io.*;public class BufferPlus{ private int buf[]= new int[10]; private int in, out; private int blk;

BufferPlus(){ in=0; out=0; blk=0;} int get_in(){ return in; } int get_out(){ return out; } void put_in(int a){ in=a; } void put_out(int b){ out=b; } void put(int i, int f){ buf[i]=f; } int get(int i){ return (int)buf[i]; }

int getblk(){ return (int)blk; } void putblk(int a){blk=a;}}

Page 184: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

184

Passaggio di parametri e sincronizzazione tra Thread

• Primo consumatore:

import java.util.*;public class ConsPlus extends Thread{ // consumatore BufferPlus buf; ConsPlus(BufferPlus p){ this.buf=p; }

public void run(){ int val;

while(true) { while( buf.getblk() == 0); { while (buf.get_out()==buf.get_in()); val=buf.get(buf.get_out()); System.out.println("\nconsumo "+val+“

out="+buf.get_out()); buf.put_out((buf.get_out()+1)%10); } buf.putblk(0); }

}}

Page 185: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

185

Passaggio di parametri e sincronizzazione tra Thread

• Secondo consumatore:

import java.util.*;public class Cons1Plus extends Thread{ // consumatore BufferPlus buf; Cons1Plus(BufferPlus p){ this.buf=p; }

public void run(){ int val;

while(true) { while(buf.getblk()==1); { while (buf.get_out()==buf.get_in()); val=buf.get(buf.get_out()); System.out.println("\ncons_1 "+val+“

out="+buf.get_out()); buf.put_out((buf.get_out()+1)%10); } buf.putblk(1); }

}}

Page 186: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

186

Monitors in Java

• La soluzione alla mutua esclusione in Java e’ data dall’uso dei monitor (Hoare)

• I monitor sono realizzati mediante i metodi synchronized: il thread che esegue un metoro synchronized di un oggetto deve preventivamente acquisire il monito associato all’oggetto

• Il monitor viene rilasciato all’uscita dal metodo

• All’interno di un metodo synchronized e’ possibile sospendere il thread che sta eseguendo attraverso l’uso dello statement wait()

• Wait provoca la sospensione del thread ed il rilascio del monitor da lui posseduto

• I thread sospesi possono essere risvegliati usando i metodi notify() e notifyAll()

• Questi metodi possono essere invocati solo all’interno di metodi synchronized

• L’effetto di notify() e notifyAll() e’ la ripresa dell’esecuzione dei thread sospesi sul monitor detenuto dal thread che esegue la notify o la notifyAll

Page 187: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

187

Esempio di monitor in Java

• Riconsideriamo l’esempio del produttore/consumatore:• Classe condivisa:

import java.io.*;public class BufferMon { private int buf[]= new int[10]; private int in, out;

BufferMon(){ in=0; out=0;} synchronized void put(int f) { if( ((in+1)%10) == out) try{ wait();} catch(InterruptedException e){}; buf[in]=f; System.out.println("produco "+f+" in="+in); in=(in+1)%10; notify(); } synchronized int get() { if(out == in) try{ wait();} catch(InterruptedException e){}; int val=buf[out]; System.out.print("get "+val+" out="+out); out=(out+1)%10; notify(); return(val); }}

Page 188: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

188

Esempio di monitor in Java

• Consumatoreimport java.util.*;public class ConsMon extends Thread{ // consumatore BufferMon buf; ConsMon(BufferMon p){ this.buf=p; }

public void run(){ while(true) { int val=buf.get(); System.out.println("cons = "+val); }

}}

• Altro cinsumatoreimport java.util.*;public class Cons1Mon extends Thread{ // consumatore BufferMon buf; Cons1Mon(BufferMon p){ this.buf=p; }

public void run(){

while(true) { int val=buf.get(); System.out.println("cons_1 = "+val); }

}}

Page 189: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

189

Esempio di monitor in Java

• Produttore:import java.util.*;public class ProdMon extends Thread{ // produttore BufferMon buf; Random r; ProdMon(BufferMon p){ this.buf=p; r=new Random(); }

public void run(){

while(true) { buf.put(r.nextInt()); }

}}

• Principale:

public class pcMon{public static void main(String[] a){

BufferMon buf=new BufferMon();

ProdMon c=new ProdMon(buf); ConsMon t=new ConsMon(buf); Cons1Mon z=new Cons1Mon(buf); c.start(); t.start(); z.start();

}}

Page 190: Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI mumolo@univ.trieste.it.

190

Breve confronto C++/Java

• Somiglianze– paradigma a oggetti– incapsulamento– ereditarietà– polimorfismo– sintassi molto simile (ad es. for, while, switch)

• Differenze– gestione della memoria

• a carico del sistema (garbage collector) o del programmatore

– uso dei puntatori– portabilità del codice– compilato– velocità di esecuzione