Progettare le Classi Progettare le Classi
C. Horstmann
C. Horstmann
Fondamenti di programmazione e Java 2
Fondamenti di programmazione e Java 2
3^ edizione Apogeo
3^ edizione Apogeo
trad. Nicola Fanizzi
trad. Nicola Fanizzi
corso di Programmazione, CdS: Informatica TPS
corso di Programmazione, CdS: Informatica TPS
Dip. di Informatica, Università degli studi di Bari
Dip. di Informatica, Università degli studi di Bari
2 2
Obiettivi Obiettivi
Imparare come scegliere le classi giuste da Imparare come scegliere le classi giuste da implementare
implementare
Capire i concetti di coesione e accoppiamento Capire i concetti di coesione e accoppiamento
Minimizzare l'uso degli effetti collaterali Minimizzare l'uso degli effetti collaterali
Documentare le responsabilità dei metodi e dei loro Documentare le responsabilità dei metodi e dei loro chiamanti con precondizioni e postcondizioni
chiamanti con precondizioni e postcondizioni
3 3
Obiettivi Obiettivi
Capire la differenza tra metodi d'istanza e metodi Capire la differenza tra metodi d'istanza e metodi statici
statici
Introdurre il concetto dei campi statici Introdurre il concetto dei campi statici
Capire le regole di visibilità per le variabili locali e i Capire le regole di visibilità per le variabili locali e i campi d'istanza
campi d'istanza
Imparare l'uso dei pacchetti Imparare l'uso dei pacchetti
4 4
Scegliere le Classi Scegliere le Classi
Una classe rappresenta un singolo concetto del Una classe rappresenta un singolo concetto del dominio del problema
dominio del problema
Il nome di una classe dovrebbe essere un sostantivo Il nome di una classe dovrebbe essere un sostantivo che descrive il concetto
che descrive il concetto
Concetti dalla matematica: Concetti dalla matematica:
Punto Punto
Rettangolo Rettangolo
Ellissi Ellissi
Concetti dalla vita reale Concetti dalla vita reale
ContoCorrente ContoCorrente
RegistratoreDiCassa RegistratoreDiCassa
5 5
Scegliere le Classi Scegliere le Classi
Attori: terminano in -or, -er (Inglese) / -ore , -ere Attori: terminano in -or, -er (Inglese) / -ore , -ere (Italiano); fanno per noi qualche tipo di lavoro (Italiano); fanno per noi qualche tipo di lavoro
Scanner Scanner
Random Random ->
-> nome migliore: nome migliore:
RandomNumberGenerator RandomNumberGenerator
Classi di Utilità: Classi di Utilità:
niente oggetti, solo metodi statici e costanti niente oggetti, solo metodi statici e costanti
Math Math
Programmi: hanno solo il metodo Programmi: hanno solo il metodo main main
Non trasformare le azioni in classi: Non trasformare le azioni in classi:
PayCheck (busta paga) migliore di ComputePayCheck (busta paga) migliore di ComputePayCheck
6 6
Coesione Coesione
Una classe deve rappresentare un singolo concetto Una classe deve rappresentare un singolo concetto
L'interfaccia pubblica di una classe è coesiva se tutte L'interfaccia pubblica di una classe è coesiva se tutte le sue caratteristiche sono relative al concetto che la le sue caratteristiche sono relative al concetto che la
classe rappresenta
classe rappresenta
7 7
Coesione Coesione
Questa classe manca di coesione: Questa classe manca di coesione:
public class CashRegister public class CashRegister { {
public void enterPayment public void enterPayment
(int dollars, int quarters, int dimes, (int dollars, int quarters, int dimes,
int nickels, int pennies) int nickels, int pennies) . . .
. . .
public static final double NICKEL_VALUE = 0.05;
public static final double NICKEL_VALUE = 0.05;
public static final double DIME_VALUE = 0.1;
public static final double DIME_VALUE = 0.1;
public static final double QUARTER_VALUE = 0.25;
public static final double QUARTER_VALUE = 0.25;
. . .
. . .
} }
8 8
Coesione Coesione
CashRegister CashRegister , come detto, riguarda due , come detto, riguarda due concetti: registratore di cassa e moneta
concetti: registratore di cassa e moneta
Soluzione: Costruire due classi Soluzione: Costruire due classi
public class Coin public class Coin {{
public Coin(double aValue, String aName){ . . . } public Coin(double aValue, String aName){ . . . } public double getValue(){ . . . }
public double getValue(){ . . . } . . .
. . . }}
public class CashRegister public class CashRegister {{
public void enterPayment public void enterPayment
(int coinCount, Coin coinType) { . . . } (int coinCount, Coin coinType) { . . . } . . .
. . . }}
9 9
Accoppiamento Accoppiamento
Una classe Una classe dipende dipende da un'altra se usa oggetti di da un'altra se usa oggetti di quella classe
quella classe
CashRegister CashRegister dipende da dipende da Coin Coin nel determinare nel determinare l'entità del pagamento
l'entità del pagamento
Coin Coin non dipende da non dipende da CashRegister CashRegister
Alto accoppiamento = molte dipendenze tra classi Alto accoppiamento = molte dipendenze tra classi
Minimizzare l'accoppiamento per minimizzare Minimizzare l'accoppiamento per minimizzare l'impatto dei cambi di
l'impatto dei cambi di interfaccia interfaccia
Per visualizzare le relazioni disegnare diagrammi di Per visualizzare le relazioni disegnare diagrammi di classe
classe
UML: Unified Modeling Language UML: Unified Modeling Language
10 10
Accoppiamento Accoppiamento
UML: Relazioni di dipendenza tra le UML: Relazioni di dipendenza tra le
classi
classi CashRegister e e Coin
11 11
Alto e Basso Alto e Basso Accoppiamento tra Classi Accoppiamento tra Classi
Figure 2
High and Low Coupling Between Classes
12 12
Accessori, Mutatori Accessori, Mutatori
e Classi Immutabili e Classi Immutabili
Accessore Accessore : non cambia lo stato del parametro : non cambia lo stato del parametro implicito
implicito
Mutatore Mutatore : modifica l'oggetto sul quale è invocato : modifica l'oggetto sul quale è invocato
double balance = account.getBalance();
double balance = account.getBalance();
account.deposit(1000);
account.deposit(1000);
13 13
Accessori, Mutatori Accessori, Mutatori
e Classi Immutabili e Classi Immutabili
Classe Immutabile Classe Immutabile : non ha metodi mutatori : non ha metodi mutatori (es.,
(es., String String ) )
È più sicuro restituire riferimenti ad istanze di classi È più sicuro restituire riferimenti ad istanze di classi immutabili; non si può modificare l'oggetto in un
immutabili; non si può modificare l'oggetto in un momento inatteso
momento inatteso
String name = "John Q. Public";
String name = "John Q. Public";
String uppercased = name.toUpperCase();
String uppercased = name.toUpperCase();
// il nome non è cambiato
// il nome non è cambiato
14 14
Effetti Collaterali Effetti Collaterali
Effetto collaterale di un metodo: Effetto collaterale di un metodo:
ogni modifica di dati osservabile esternamente ogni modifica di dati osservabile esternamente
Aggiornare un parametro esplicito può risultare Aggiornare un parametro esplicito può risultare qualcosa di inaspettato per altri programmatori qualcosa di inaspettato per altri programmatori
meglio evitare, se possibile meglio evitare, se possibile
public void transfer(double amount, BankAccount other) public void transfer(double amount, BankAccount other) { {
balance = balance - amount;
balance = balance - amount;
other.balance = other.balance + amount;
other.balance = other.balance + amount;
// Modifica il parametro esplicito
// Modifica il parametro esplicito
} }
15 15
Effetti Collaterali Effetti Collaterali
Un altro esempio di effetto collaterale è l'output Un altro esempio di effetto collaterale è l'output
Cattiva idea: il messaggio è in inglese e si usa Cattiva idea: il messaggio è in inglese e si usa System.out
System.out
Meglio disaccoppiare l'input/output dal lavoro reale delle Meglio disaccoppiare l'input/output dal lavoro reale delle classi
classi
Si deve minimizzare gli effetti collaterali che vanno Si deve minimizzare gli effetti collaterali che vanno oltre la modifica del parametro implicito
oltre la modifica del parametro implicito
public void printBalance() // non raccomndabile public void printBalance() // non raccomndabile { {
System.out.println("The balance is now $" + balance);
System.out.println("The balance is now $" + balance);
} }
16 16
Errore Comune: Modificare un Errore Comune: Modificare un
Parametro di Tipo Primitivo Parametro di Tipo Primitivo
Non funziona Non funziona
Scenario: Scenario:
In Java, un metodo non può modificare alcun In Java, un metodo non può modificare alcun parametro di tipo primitivo
parametro di tipo primitivo
void transfer(double amount, double otherBalance) void transfer(double amount, double otherBalance) { {
balance = balance - amount;
balance = balance - amount;
otherBalance = otherBalance + amount;
otherBalance = otherBalance + amount;
} }
double savingsBalance = 1000;
double savingsBalance = 1000;
harrysChecking.transfer(500, savingsBalance);
harrysChecking.transfer(500, savingsBalance);
System.out.println(savingsBalance);
System.out.println(savingsBalance);
17 17
Modifica Parametro Numerico Modifica Parametro Numerico
Nessun Effetto sul Chiamante Nessun Effetto sul Chiamante
Figure 3(1):
Modifying a Numeric Parameter Has No Effect on Caller
18 18
Modifica Parametro Numerico Modifica Parametro Numerico
Nessun Effetto sul Chiamante Nessun Effetto sul Chiamante
Figure 3(2):
Modifying a Numeric Parameter Has No Effect on Caller
19 19
Modifica Parametro Numerico Modifica Parametro Numerico
Nessun Effetto sul Chiamante Nessun Effetto sul Chiamante
Figure 3(3):
Modifying a Numeric Parameter Has No Effect on Caller
20 20
Modifica Parametro Numerico Modifica Parametro Numerico
Nessun Effetto sul Chiamante Nessun Effetto sul Chiamante
Figure 3(4):
Modifying a Numeric Parameter Has No Effect on Caller
21 21
Chiamata Chiamata per Valore e per Riferimento per Valore e per Riferimento
Chiamata per valore Chiamata per valore : i parametri del metodo sono : i parametri del metodo sono copiati nelle variabili parametro quando il metodo copiati nelle variabili parametro quando il metodo
comincia la sua esecuzione comincia la sua esecuzione
Chiamata per riferimento Chiamata per riferimento : i metodi possono : i metodi possono modificare direttamente i parametri
modificare direttamente i parametri
Java ammette chiamate per valore Java ammette chiamate per valore
22 22
Chiamata Chiamata per Valore e per Riferimento per Valore e per Riferimento
Un metodo Un metodo può può cambiare lo stato di parametri che cambiare lo stato di parametri che sono riferimenti ad oggetti, ma
sono riferimenti ad oggetti, ma non può non può sostituire un sostituire un riferimento ad oggetto con un altro
riferimento ad oggetto con un altro
public class BankAccount public class BankAccount { {
public void transfer public void transfer
(double amount, BankAccount otherAccount) (double amount, BankAccount otherAccount) { {
balance = balance - amount;
balance = balance - amount;
double newBalance = otherAccount.balance + amount;
double newBalance = otherAccount.balance + amount;
otherAccount = new BankAccount(newBalance);
otherAccount = new BankAccount(newBalance);
// non funziona // non funziona } }
} }
23 23
Esempio: Chiamata per Valore Esempio: Chiamata per Valore
Figure 4:
Modifying an Object Reference Parameter Has No Effect on the Caller
harrysChecking.transfer(500, savingsAccount);
harrysChecking.transfer(500, savingsAccount);
24 24
Precondizioni Precondizioni
Precondizione Precondizione : Vincolo che il chiamante di un : Vincolo che il chiamante di un metodo deve soddisfare
metodo deve soddisfare
Rendere pubbliche le precondizioni in modo che il Rendere pubbliche le precondizioni in modo che il
chiamante non invocherà metodi passando parametri chiamante non invocherà metodi passando parametri
sbagliati sbagliati
/** /**
Deposita denaro sul conto.
Deposita denaro sul conto.
@param amount la cifra da depositare @param amount la cifra da depositare (Precondizione: amount >= 0)
(Precondizione: amount >= 0)
*/ */
25 25
Precondizioni Precondizioni
Uso Tipico: Uso Tipico:
Porre restrizioni sui parametri di un metodo Porre restrizioni sui parametri di un metodo
Richiedere che un metodo venga invocato quando Richiedere che un metodo venga invocato quando l'oggetto è nello stato appropriato
l'oggetto è nello stato appropriato
Se viene violata una precondizione, il metodo Se viene violata una precondizione, il metodo non non è è più responsabile del calcolo del corretto risultato.
più responsabile del calcolo del corretto risultato.
È libero di fare qualsiasi cosa
È libero di fare qualsiasi cosa
26 26
Precondizioni Precondizioni
Un metodo può lanciare una eccezione qualora una Un metodo può lanciare una eccezione qualora una precondizione venga violata (cfr. Cap. 14)
precondizione venga violata (cfr. Cap. 14)
Un metodo non è obbligato a testare la Un metodo non è obbligato a testare la
precondizione (il test potrebbe essere costoso) precondizione (il test potrebbe essere costoso)
if (amount < 0) throw new IllegalArgumentException();
if (amount < 0) throw new IllegalArgumentException();
balance = balance + amount;
balance = balance + amount;
// se il saldo diventa negativo, è colpa del chiamante // se il saldo diventa negativo, è colpa del chiamante
balance = balance + amount;
balance = balance + amount;
27 27
Precondizioni Precondizioni
Un metodo può fare il controllo di un'asserzione Un metodo può fare il controllo di un'asserzione
Per abilitare il controllo delle asserzioni: Per abilitare il controllo delle asserzioni:
java -enableassertions MyProg java -enableassertions MyProg
Si possono disabilitare le asserzioni Si possono disabilitare le asserzioni dopo dopo aver aver testato il programma, in modo da farlo girare alla testato il programma, in modo da farlo girare alla
massima velocità massima velocità
assert amount >= 0;
assert amount >= 0;
balance = balance + amount;
balance = balance + amount;
28 28
Precondizioni Precondizioni
Molti programmatori inesperti in tali casi fanno Molti programmatori inesperti in tali casi fanno tornare tacitamente al chiamante
tornare tacitamente al chiamante
if (amount < 0) return;
if (amount < 0) return;
// poco raccomandabile;
// poco raccomandabile;
// difficile da debuggare // difficile da debuggare balance = balance + amount;
balance = balance + amount;
29 29
Sintassi 9.1: Asserzione Sintassi 9.1: Asserzione
assert assert condition condition ; ;
Esempio Esempio : :
assert amount >= 0; assert amount >= 0;
Scopo Scopo : asserire che una condizione è soddisfatta. : asserire che una condizione è soddisfatta.
Se il controllo è abilitato e la condizione è falsa, Se il controllo è abilitato e la condizione è falsa,
viene lanciato un errore di asserzione
viene lanciato un errore di asserzione
30 30
Postcondizioni Postcondizioni
Postcondizione Postcondizione : Condizione che è vera dopo che : Condizione che è vera dopo che un metodo è stato completato
un metodo è stato completato
Se la chiamata del metodo Se la chiamata del metodo soddisfa soddisfa le precondizioni le precondizioni deve assicurare che le postcondizioni siano valide deve assicurare che le postcondizioni siano valide
Ci sono due tipi di postcondizioni: Ci sono due tipi di postcondizioni:
Il valore da restituire venga calcolato correttamente Il valore da restituire venga calcolato correttamente
L'oggetto è in un determinato stato dopo che la chiamata L'oggetto è in un determinato stato dopo che la chiamata del metodo sia completata
del metodo sia completata
31 31
Postcondizioni Postcondizioni
Non serve documentare postcodizioni ovvie che Non serve documentare postcodizioni ovvie che replichino la clausola
replichino la clausola @return @return
/** /**
Deposita denaro su questo conto.
Deposita denaro su questo conto.
(Postcondizione: getBalance() >= 0) (Postcondizione: getBalance() >= 0) @param amount la cifra da depositare @param amount la cifra da depositare (Precondizione: amount >= 0)
(Precondizione: amount >= 0)
*/ */
32 32
Postcondizioni Postcondizioni
Formulare pre- e postcondizioni solo in termini Formulare pre- e postcondizioni solo in termini dell'interfaccia della classe
dell'interfaccia della classe
Contratto Contratto : se il chiamante soddisfa le precondizioni, : se il chiamante soddisfa le precondizioni, il metodo soddisferà la postcondizione
il metodo soddisferà la postcondizione
amount <= getBalance() amount <= getBalance()
// maniera giusta di dichiarare una postcondizione // maniera giusta di dichiarare una postcondizione amount <= balance
amount <= balance
// formulazione sbagliata
// formulazione sbagliata
33 33
Metodi Statici Metodi Statici
Ogni metodo Ogni metodo deve deve trovarsi in una classe trovarsi in una classe
Un metodo statico non viene invocato su un oggetto Un metodo statico non viene invocato su un oggetto
Perché Perché scrivere un metodo che non opera su un scrivere un metodo che non opera su un oggetto?
oggetto?
Ragione generale: incapsulare calcoli che non Ragione generale: incapsulare calcoli che non
riguardano solo numeri. I
riguardano solo numeri. I numeri numeri non sono oggetti, non sono oggetti, non si possono invocare metodi su di essi
non si possono invocare metodi su di essi
Es: Es: x.sqrt() x.sqrt() non sarà mai lecito in Java non sarà mai lecito in Java
34 34
Metodi Statici Metodi Statici
Chiamata su una classe invece di un oggetto: Chiamata su una classe invece di un oggetto:
main main è statico – non ci sarebbero ancora oggetti su è statico – non ci sarebbero ancora oggetti su cui invocarlo
cui invocarlo
public class Financial public class Financial { {
public static double percentOf(double p, double a) public static double percentOf(double p, double a) { {
return (p / 100) * a;
return (p / 100) * a;
} }
// Si possono aggiungere altri metodi di // Si possono aggiungere altri metodi di
matematica finanziaria matematica finanziaria } }
double tax = Financial.percentOf(taxRate, total);
double tax = Financial.percentOf(taxRate, total);
35 35
Campi
Campi static static
Un campo static appartiene alla classe e non ad un Un campo static appartiene alla classe e non ad un qualunque
qualunque oggetto della classe. oggetto della classe.
Si chiama anche
Si chiama anche campo di classe campo di classe . .
Se Se lastAssignedNumber lastAssignedNumber non fosse static, ogni non fosse static, ogni istanza di
istanza di BankAccount BankAccount avrebbe il suo valore di avrebbe il suo valore di lastAssignedNumber
lastAssignedNumber
public class BankAccount public class BankAccount { {
. . . . . .
private double balance;
private double balance;
private int accountNumber;
private int accountNumber;
private static int lastAssignedNumber = 1000;
private static int lastAssignedNumber = 1000;
} }
36 36
Campi
Campi static static
Minimizzare l'uso di campi statici Minimizzare l'uso di campi statici
(vanno bene campi statici che siano anche final) (vanno bene campi statici che siano anche final)
public BankAccount() public BankAccount() { {
// Genera il prossimo numero conto da assegnare // Genera il prossimo numero conto da assegnare lastAssignedNumber++; // Updates the static field lastAssignedNumber++; // Updates the static field
// assegna il campo numero conto presso questa banca // assegna il campo numero conto presso questa banca account accountNumber = lastAssignedNumber;
account accountNumber = lastAssignedNumber;
// imposta il campo istanza // imposta il campo istanza
} }
37 37
Campi
Campi static static
Tre modalità di Tre modalità di inizializzazione inizializzazione : :
1) 1) Non far nulla. Il campo assume 0 Non far nulla. Il campo assume 0 (per numeri), false (per numeri), false (valori booleani), o
(valori booleani), o null null (per oggetti) (per oggetti) 2) 2) Usare una esplicita inizializzazione, come Usare una esplicita inizializzazione, come
3) 3) Usare un blocco di inizializzazione statica Usare un blocco di inizializzazione statica
public class BankAccount public class BankAccount { {
. . . . . .
private static int lastAssignedNumber = 1000;
private static int lastAssignedNumber = 1000;
// eseguto una sola volta, // eseguto una sola volta,
// al caricamento della classe
// al caricamento della classe
} }
38 38
Campi
Campi static static
3) 3) Usare un blocco di inizializzazione (statico) Usare un blocco di inizializzazione (statico)
NB: vale anche per inizializzare i campi d'istanza;
NB: vale anche per inizializzare i campi d'istanza;
in tal caso occorre omettere la parola chiave
in tal caso occorre omettere la parola chiave static static
public class BankAccount public class BankAccount { {
. . . . . .
private static int lastAssignedNumber;
private static int lastAssignedNumber;
static static { {
lastAssignedNumber = 1000;
lastAssignedNumber = 1000;
} }
} }
39 39
Campi
Campi static static
I campi statici andrebbero dichiarati sempre come I campi statici andrebbero dichiarati sempre come private
private
Eccezione Eccezione : Costanti statiche, che potrebbero essere : Costanti statiche, che potrebbero essere sia sia private private sia sia public public
public class BankAccount public class BankAccount { {
. . . . . .
public static final double OVERDRAFT_FEE = 5;
public static final double OVERDRAFT_FEE = 5;
// Vi si fa riferimento con
// Vi si fa riferimento con
// BankAccount.OVERDRAFT_FEE
// BankAccount.OVERDRAFT_FEE
} }
40 40
Campi di Classe e di Istanza
Campi di Classe e di Istanza
41 41
Visibilità delle Variabili Locali Visibilità delle Variabili Locali
Visibilità Visibilità ( ( scope scope ) di una variabile: ) di una variabile:
regione del programma nella quale si può accedere regione del programma nella quale si può accedere
alla variabile alla variabile
La visibilità di una variabile locale si estende dalla La visibilità di una variabile locale si estende dalla sua dichiarazione alla fine del blocco
sua dichiarazione alla fine del blocco che che la la racchiude
racchiude
42 42
Visibilità delle Variabili Locali Visibilità delle Variabili Locali
A volte si può usare lo stesso nome di variabile in A volte si può usare lo stesso nome di variabile in due metodi.
due metodi.
Tali variabili sono mutuamente indipendenti; Tali variabili sono mutuamente indipendenti;
le loro visibilità sono disgiunte
le loro visibilità sono disgiunte
43 43
Visibilità delle Variabili Locali Visibilità delle Variabili Locali
public class RectangleTester public class RectangleTester { {
public static double area(Rectangle rect) public static double area(Rectangle rect) { {
double r = rect.getWidth() * rect.getHeight();
double r = rect.getWidth() * rect.getHeight();
return r;
return r;
} }
public static void main(String[] args) public static void main(String[] args) { {
Rectangle r = new Rectangle(5, 10, 20, 30);
Rectangle r = new Rectangle(5, 10, 20, 30);
double a = area(r);
double a = area(r);
System.out.println(r);
System.out.println(r);
} }
} }
44 44
Visibilità delle Variabili Locali Visibilità delle Variabili Locali
Lo scope di una variabile locale Lo scope di una variabile locale non non può contenere può contenere la definizione di un'altra variabile con lo stesso nome la definizione di un'altra variabile con lo stesso nome
Rectangle r = new Rectangle(5, 10, 20, 30);
Rectangle r = new Rectangle(5, 10, 20, 30);
if (x >= 0) if (x >= 0) { {
double r = Math.sqrt(x);
double r = Math.sqrt(x);
// Errore // Errore
non puoi dichiarare qui un'altra var. chiamata r non puoi dichiarare qui un'altra var. chiamata r . . .
. . .
} }
45 45
Visibilità delle Variabili Locali Visibilità delle Variabili Locali
Tuttavia, ci possono essere variabioli locali con nomi Tuttavia, ci possono essere variabioli locali con nomi identici se gli scope non si sovrappongono
identici se gli scope non si sovrappongono
if (x >= 0) if (x >= 0) { {
double r = Math.sqrt(x);
double r = Math.sqrt(x);
. . . . . .
} // lo scope di r finisce qui } // lo scope di r finisce qui else else
{ {
Rectangle r = new Rectangle(5, 10, 20, 30);
Rectangle r = new Rectangle(5, 10, 20, 30);
// OK–qui è lecito dichiarare un'altra r // OK–qui è lecito dichiarare un'altra r . . .
. . .
} }
46 46
Visibilità di Classe Visibilità di Classe
I membri I membri private private hanno uno scope di classe: hanno uno scope di classe:
si può accedere a tutti i membri in qualunque si può accedere a tutti i membri in qualunque
metodo all'interno della classe metodo all'interno della classe
Al di fuori della classe, occorre qualificare i membri Al di fuori della classe, occorre qualificare i membri pubblici
pubblici
Math.sqrt Math.sqrt
harrysChecking.getBalance
harrysChecking.getBalance
47 47
Scope dei Membri della Classe Scope dei Membri della Classe
All'interno di un metodo non serve qualificare i campi All'interno di un metodo non serve qualificare i campi e i metodi che appartengono alla data classe
e i metodi che appartengono alla data classe
Un campo o metodo d'istanza non qualificatosi Un campo o metodo d'istanza non qualificatosi riferisce al parametro
riferisce al parametro this this
public class BankAccount public class BankAccount { {
public void transfer(double amount, BankAccount other) public void transfer(double amount, BankAccount other) { {
withdraw(amount);
withdraw(amount); // ovvero this.withdraw(amount); // ovvero this.withdraw(amount);
other.deposit(amount);
other.deposit(amount);
} } ...
...
} }
48 48
Visibilità Sovrapposte Visibilità Sovrapposte
Una variabile locale può oscurare ( Una variabile locale può oscurare ( shadow shadow ) un ) un campo con lo stesso nome
campo con lo stesso nome
Lo scope locale vince su quello di classe Lo scope locale vince su quello di classe
public class Coin public class Coin { {
. . . . . .
public double getExchangeValue(double exchangeRate) public double getExchangeValue(double exchangeRate) { {
double value;
double value; // Variabile locale // Variabile locale . . .
. . .
return value;
return value;
} }
private String name;
private String name;
private double value;
private double value; // Campo con lo stesso nome // Campo con lo stesso nome
} }
49 49
Visibilità Sovrapposte Visibilità Sovrapposte
Si accede a campi oscurati qualificandoli con il Si accede a campi oscurati qualificandoli con il riferimento
riferimento this this
value = this.value * exchangeRate;
value = this.value * exchangeRate;
50 50
Organizzare Classi Correlate Organizzare Classi Correlate
in Package in Package
Package: insieme di classi correlate Package: insieme di classi correlate
Per assegnare alcune classi in un package, Per assegnare alcune classi in un package, si deve mettere una riga
si deve mettere una riga
come prima istruzione del sorgente contenente le come prima istruzione del sorgente contenente le
classi classi
Il nome di un pacchetto consiste in uno o più Il nome di un pacchetto consiste in uno o più identificatori separati da punti
identificatori separati da punti
package packageName;
package packageName;
51 51
Organizzare Classi Correlate Organizzare Classi Correlate
in Package in Package
Ad esempio, per mettere la classe Ad esempio, per mettere la classe Financial Financial nel package
nel package com.horstmann.bigjava com.horstmann.bigjava , , il file
il file Financial.java Financial.java deve cominciare come deve cominciare come segue:
segue:
Il Il package package di default non ha nome nè serve di default non ha nome nè serve qualificarlo con un'istruzione
qualificarlo con un'istruzione package package
package com.horstmann.bigjava;
package com.horstmann.bigjava;
public class Financial public class Financial { {
. . .
. . .
} }
52 52
Organizzare Classi Correlate Organizzare Classi Correlate
in Package in Package
IntHolder IntHolder Common Object Request Broker
Common Object Request Broker Architecture
Architecture Org.omg.CORBA
Org.omg.CORBA
JButton JButton Swing user interface
Swing user interface Java.swing
Java.swing
ResultSet ResultSet Accesso ai Database
Accesso ai Database Java.sql
Java.sql
Socket Socket Networking
Networking Java.net
Java.net
Applet Applet Applet
Applet Java.applet
Java.applet
Color Color Abstract Windowing Toolkit
Abstract Windowing Toolkit Java.awt
Java.awt
PrintScreen PrintScreen Input e Output
Input e Output java.io
java.io
Random Random Utilità
Utilità java.util
java.util
MathMath Supporto al linguaggio
Supporto al linguaggio java.lang
java.lang
Esempio Esempio Scopo
Scopo Package
Package
53 53
Sintassi 9.2:
Sintassi 9.2:
Specifica dei Package Specifica dei Package
package
package packageName packageName ; ;
Esempio Esempio : :
package it.uniba.di.fanizzi;
package it.uniba.di.fanizzi;
Scopo Scopo : per dichiarare che tutte le classi nel file : per dichiarare che tutte le classi nel file
presente appartiene ad un particolare package
presente appartiene ad un particolare package
54 54
Importare dai Package Importare dai Package
java.util.Scanner in = new java.util.Scanner in = new
java.util.Scanner(System.in);
java.util.Scanner(System.in);
import java.util.Scanner;
import java.util.Scanner;
. . . . . .
Scanner in = new Scanner(System.in) Scanner in = new Scanner(System.in)
Si può sempre usare una classe senza importarla Si può sempre usare una classe senza importarla
Usare nomi qualificati è tedioso Usare nomi qualificati è tedioso
Usare Usare import import permette di usare nomi più corti permette di usare nomi più corti
55 55
Importare dai Package Importare dai Package
import java.util.*;
import java.util.*;
Si possono importare tutte le classi in un package Si possono importare tutte le classi in un package
Non c'è mai bisogno di importare Non c'è mai bisogno di importare java.lang java.lang
Non c'è bisogno di importare altre classi nello stesso Non c'è bisogno di importare altre classi nello stesso package
package
56 56
I Nomi di Package I Nomi di Package e Localizzare le Classi e Localizzare le Classi
Su usano i package per evitare collisioni di nomi Su usano i package per evitare collisioni di nomi
I nomi di package dovrebbero essere non ambigui I nomi di package dovrebbero essere non ambigui
Raccomandazione: Raccomandazione:
iniziare invertendo il nome del dominio iniziare invertendo il nome del dominio
edu.sjsu.cs.walters
edu.sjsu.cs.walters : per le classi di : per le classi di Bertha Walters (
Bertha Walters ( walters@cs.sjsu.edu walters@cs.sjsu.edu ) )
java.util.Timer vs. javax.swing.Timer java.util.Timer vs. javax.swing.Timer
com.horstmann.bigjava
com.horstmann.bigjava
57 57
I Nomi di Package I Nomi di Package e Localizzare le Classi e Localizzare le Classi
La stringa del path dovrebbe corrispondere al nome La stringa del path dovrebbe corrispondere al nome del package:
del package:
Il nome del percorso inizia con il percorso della Il nome del percorso inizia con il percorso della classe:
classe:
CLASSPATH CLASSPATH contiene le directory di base che contiene le directory di base che possono contenere directory di package
possono contenere directory di package
com/horstmann/bigjava/Financial.java com/horstmann/bigjava/Financial.java
export CLASSPATH=/home/walters/lib:.
export CLASSPATH=/home/walters/lib:.
set CLASSPATH=c:\home\walters\lib;.
set CLASSPATH=c:\home\walters\lib;.
58 58
Directory di Base e Directory di Base e Sottodirectories per Package Sottodirectories per Package
Figure 6:
Base Directories and Subdirectories for Packages