Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
CARATTERISTICHE FONDAMENTALI DELLA PROGRAMMAZIONE AD OGGETTI!
!
Una buona OOP (Object Oriented Programmy) deve basarsi su tre principi fondamentali:!
! • !
Incapsulamento, cioè racchiudere all'interno di una classe attributi e metodi
• !
Ereditarietà, possibilità di definire classi a partire da classi già esistenti
• Polimorfismo, possibilità i definire metodi con la stessa intestazione che però possono avere
!
comportamenti differenti
Tali concetti saranno meglio approfonditi in seguito.!
!
IL FORMALISMO UML (UNIFIED MODELLING LANGUAGE)!
!
Il formalismo UML serve a dare una rappresentazione grafica utile per lo sviluppo di un programma. Una
classe è un rettangolo diviso in tre sezioni: Nome classe, Attributi e Metodi. Un oggetto di una classe è
rappresentato come un rettangolo dai bordi arrotondati diviso in due sezioni: NomeOggetto, attributi. Ad
esempio la classe macchina sarà rappresentata come un rettangolo con nella prima sezione (quella più in
alto) Automobile, nella seconda ci sarà l'elenco degli attributi(marca, modello, colore,...) nella terza sezione
vi sarà l'elenco dei metodi preceduti da un + o da un -, nel primo caso i metodi saranno pubblici nel secondo
caso saranno privati, metodi come accelera, decelera, frena,...!
Un oggetto di questa classe sarà rappresentato come un rettangolo dagli spigoli arrotondati con nella prima
sezione MiaAutomobile, nella seconda (Lancer, EvolutionX, nero,...).!
!
EREDITARIETA'!
!
L'ereditarietà è una delle caratteristiche fondamentali della programmazione ad oggetti e consiste
fondamentalmente nella possibilità di definire una classe non ex-novo, ma ritrovando nel codice già
sviluppato una classe avente caratteristiche comuni a quella che noi vogliamo realizzare e quindi creare
nuove classi a partire da classi già esistenti. Non necessariamente siamo noi a dover definire una classe,
ma in ogni caso si possono ritrovare classi "imparentate" tra loro.!
33 di 69
!
La classe da cui partono le nuove classi è detta superclasse o classe madre le classi definite a partire da
essa sono dette classi derivate o classi figlie. !
!
Per riconoscere in maniera spedita se una classe può essere derivata da un'altra ci si può porre la seguente
domanda:!
!
classe derivata IS A superclasse?!
!
ossia se la classe derivata può essere considerata come un oggetto della superclasse, ma specializzato
ovvero estende la superclasse con attributi e metodi. Per esempio, supponiamo di avere una classe Persona
e una classe Studente ci si pone la domanda:!
!
Studente IS A Persona?!
!
La risposta è ovviamente sì e quindi risulta naturale capire che la classe Persona è classe madre di
Studente, o viceversa Studente è classe figlia di Persona.!
!
Quando si definisce una classe derivata da un'altra, essa contiene tutti i metodi e gli attributi della
superclasse, ma esistono mezzi per ridefinirla.!
!
In Java la parola chiave per definire che una classe deriva da un'altra è extends. Infatti si dice che una
classe derivata è un'estensione della superclasse.!
!
LE FIGURE GEOMETRICHE DEL PACKAGE PROG.UTILI!
!
Detto ciò un esempio esplicativo del discorso della gerarchia tra classi lo troviamo cercando di creare
programmi riguardanti le figure geometriche. Dalla documentazione del package prog notiamo che esistono
diverse classi capaci di rappresentare figure geometriche, ad esempio la classe Rettangolo, Quadrato,
Cerchio,...!
Prendiamo ora in esame tali classi al fine di trarne conclusioni utili per la comprensione del discorso
precedentemente affrontato.!
!
La classe Rettangolo!
!
Questa classe come dice il nome serve a generare rettangoli.!
Il prototipo del costruttore è:!
!
public Rettangolo(double base, double altezza);!
!
Gli attributi della classe saranno:!
! • !
base
• !
altezza
Alcuni metodi che possono essere invocati sono:!
! • !
public double getArea();
• !
public double getPerimetro();
• !
public double getBase();
• !
public double getAltezza();
• !
public boolean haAreaMaggiore(Rettangolo b);
• !
public boolean haPerimetroMaggiore(Rettangolo b);
• !
public String toString(); 34 di 69
Supponiamo ora di voler scrivere un programma che riceve in input una serie di Rettangoli e in Output deve
stampare il Rettangolo di area maggiore:!
!
import prog.io.*;!
import prog.utili.*;!
!
public class AreaRMax!
{! public static void main(String [] args)!
{! ConsoleInputManager in=new ConsoleInputManager();!
ConsoleOutputManager out=new ConsoleOutputManager();!
Rettangolo max=null; // non è ancora stato inserito nessun rettangolo quindi lo si inizializza con
null, mai usare un valore per max!
Rettangolo r;!
do!
{! r=new Rettangolo(in.readDouble("Inserisci base "), in.readDouble("Inserisci altezza "));!
if(r==null || r.haAreaMaggiore(max)) !
max=r;!
! }while(in.readSiNo("Ancora? ");!
out.println("Il rettangolo con area maggiore è "+max);!
}!
}!
!!
Poniamo attenzione alla funzione dell'if all'interno del do while: se è la prima volta che viene fatto il ciclo
allora max viene settato a r, se no c'è il controllo sull'Area. è inoltre importante la Lazy Evaluation perchè alla
prima volta che il ciclo viene effettuato se non ci fosse si farebbe un controllo tra r e max che punta a null,
dando errore.!
!
Ora pensiamo a voler svolgere lo stesso esercizio, ma l'utente in ingresso può dare o un oggetto della
classe Rettangolo o un oggetto della classe Quadrato, in ogni caso in uscita si vuole sapere quale figura ha
l'Area maggiore.!
Prima di tutto prendiamo in esame la struttura della classe Quadrato.!
!
La classe Quadrato!
!
Il prototipo del costruttore è:!
!
public Quadrato(double lato);!
!
Un attributo può essere!
!
lato!
!
Alcuni metodi invocabili sono:!
! • !
public double getArea();
• !
public double getPerimetro();
• !
public double getLato();
• !
public boolean haAreaMaggiore();
• !
public boolean haPerimetroMaggiore();
• !
public String toString(); 35 di 69
Ora volendo scrivere il programma di prima ci accorgiamo che non conoscendo i concetti di gerarchia delle
classi vi potrebbero essere problemi per via dell'eterogeneità dei dati inseriti. Tuttavia risulta naturale porsi la
domanda!
!
Quadrato IS A Rettangolo?!
!
Effettivamente sì, perchè un Quadrato non è altro che un Rettangolo con base e altezza uguali, pertanto
possiamo pensare che vi è "parentela" tra queste classi, in particolare possiamo pensare che Quadrato è
un'estensione di Rettangolo. !
In effetti si può notare come la classe Quadrato contenga tutti i metodi della classe Rettangolo (seguendo
appunto l'idea di ereditarietà), però contiene anche un metodo in più: getLato();!
Inoltre il metodo toString() per il rettangolo stampa una stringa in cui indica base e altezza, cosa poco
pertinente per un quadrato visto che sono uguali, tuttavia il metodo toString() applicato a Quadrato si
comporta in maniera differente, stampa in fatti una stringa in cui descrive la lunghezza del lato. Questo
accade in quanto il metodo toString() viene riscritto nella classe Quadrato perchè sia più pertinente, tale
fenomeno è detto overriding.!
!
Nel caso di overriding, come si può notare, i metodi hanno la stessa intestazione (il metodo toString() di
Rettangolo ha la stessa intestazione di quello di Quadrato), pertanto il compilatore non è in grado di
espandere il codice in fase di compilazione, appunto perchè è l'oggetto chiamante a determinare il metodo
della classe più pertinente da richiamare, pertanto questa scelta viene effettuata in runtime. L'ovverriding è
un fenomeno di polimorfismo, più precisamente di polimorfismo puro. Se due metodi hanno invece la stessa
intestazione, ma diversi parametri in ingresso allora il compilatore è in grado di capire come estendere il
codice in fase di compilazione, si parla allora di overloading.!
!
Inoltre nell'esempio Rettangolo-Quadrato, si può notare una gerarchia a livello di tipi. In questo caso
Rettangolo è supertipo della classe Quadrato e pertanto Rettangolo può contenere anche un Quadrato.!
Per esempio:!
...!
Rettangolo r;!
Quadrato q=new Quadrato(6);!
r=q;!
...!
!
equivalentemente!
!
Rettangolo r=new Quadrato(6);!
!
Anche i metodi possono avere come argomenti dei sottotipi(in questo caso Quadrato è sottotipo di
Rettangolo), per esempio:!
!
Rettangolo r=new Rettangolo(3,4);!
Quadrato q=new Quadrato(3);!
boolean b=r.haAreaMaggiore(q);!
!
Per testare la natura del dell'oggetto si usa il predicato instanceof, è molto importante sottolineare che NON
è un metodo, quindi niente punti, niente maiuscole e niente parentesi, ad esempio:!
!
r instanceof Quadrato!
!
Restituisce true se r appartiene alla classe Quadrato, false altrimenti.!
Bisogna notare però che supponendo di avere un Quadrato q, se utilizzo il predicato come segue:!
!
r instanceof Rettangolo!
!
Restituirebbe true, perchè Quadrato è classe figlia di Rettangolo pertanto Quadrato IS A Rettangolo, quindi
fare molta attenzione.!
!
Ora l'esercizio di prima è svolgibile come segue:! 36 di 69
!
...!
Rettangolo r;!
Rettangolo max=null; // utilizzo come tipo Rettangolo in quanto esso può contenere anche oggetti della
classe Quadrato!
double x;!
double y;!
do!
{! x=in.readDouble("Base? ");!
y=in.readDouble("Altezza? ");!
if(x==y)!
{! r=new Quadrato(x);!
}else!
{! r=new Rettangolo(x,y);!
}!
if(r==null || r.haAreaMaggiore(max))!
max=r;!
}while(in.readSiNo("Ancora? ");!
out.println("La figura di area maggiore è un ");!
if(max instanceof Quadrato)!
out.println("Quadrato ");!
else!
out.println("Rettangolo ");!
!
out.println(max.toString());!
!
...!
!
Come si può ben vedere dal programma sopra riportato i cambiamenti rispetto all'implementazione
precedente sono minimi e inoltre bisogna porre molta attenzione al controllo finale per sapere a che classe
appartiene max: prima si controlla che sia un Quadrato e poi che sia u