Capitolo 10 Ereditarietà - DEI

Obiettivi
Capitolo 10
Ereditarietà
Imparare cos’è l’ereditarietà
| Capire come ereditare e sovrascrivere i
metodi superclasse
| Invocare il costruttore della superclasse
| I controlli d’eccesso protected e package
| La superclasse Object e i metodi toString
e equals
|
Fondamenti Informatica
Introduzione all’ereditarietà
Ereditarietà
z
|
estendere classi aggiungendo metodi e
campi
// Savings account with 10% interest
collegeFund.deposit(500);
// OK to use BankAccount method with SavingsAccount object
Classe estesa = Superclasse (BankAccount),
| Classe che estende = Sottoclasse (Savings)
|
class SavingsAccount extends BankAccount
{
new methods
new instance fields
}
UNIPD 2007
SavingsAccount automaticamente eredita
metodi e le istanze di BankAccount
SavingsAccount collegeFund = new SavingsAccount(10);
Es: conto di risparmio = Conto corrente
bancario con interessi
Fondamenti Informatica
2
Introduzione all’ereditarietà
|
|
UNIPD 2007
3
Fondamenti Informatica
UNIPD 2007
4
1
Introduzione all’ereditarietà
|
Ereditare da una classe ≠ implementare
interfaccia
z
|
Diagramma dell’ereditarietà
|
la sottoclasse eredita comportamento e
stato
Un vantaggio dell’ereditarietà è il riutilizzo di
codice
Fondamenti Informatica
UNIPD 2007
5
Ogni classe
estende la classe
Object direttamente
o indirettamente
Fondamenti Informatica
Introduzione all’ereditarietà
|
UNIPD 2007
6
Introduzione all’ereditarietà
Sottoclasse specifica le istanze aggiunte, i metodi
aggiunti, e i metodi modificati o riscritti
|
Incapsulamento
z
public class SavingsAccount extends BankAccount
{
public SavingsAccount(double rate)
{
interestRate = rate;
}
public void addInterest()
{
double interest = getBalance() * interestRate / 100;
deposit(interest);
}
z
|
addInterest chiama getBalance
non può aggiornare il campo balance della
superclasse (xché il campo è private)
Nota che addInterest chiama
getBalance senza specificare un
parametro implicito
(la chiamata si applica allo stesso oggetto)
private double interestRate;
Fondamenti Informatica
}
UNIPD 2007
7
Fondamenti Informatica
UNIPD 2007
8
2
Layout di un oggetto
Sottoclasse
|
Sintassi 10.1: Ereditarietà
L’oggetto SavingsAccount eredita
l’istanza di balance da BankAccount, e
guadagna un’altra istanza: interestRate
Fondamenti Informatica
UNIPD 2007
9
class SubclassName extends SuperclassName
{
methods
instance fields
}
Fondamenti Informatica
Sintassi 10.1: Ereditarietà
UNIPD 2007
Verifica
Example:
public class SavingsAccount extends BankAccount {
public SavingsAccount(double rate)
{
interestRate = rate;
}
public void addInterest()
{
double interest = getBalance() * interestRate / 100;
deposit(interest);
}
private double interestRate;
}
1.
Quale campo istanza ha un oggetto della
classe SavingsAccount?
2.
Elencare i 4 metodi che puoi applicare
all’oggetto SavingsAccount
Se la classe Manager estende la classe
Employee, qual’è la Superclasse e quale
la Sottoclasse?
3.
Purpose:
To define a new class that inherits from an existing class, and define the
methods and instance fields that are added in the new class.
Fondamenti Informatica
UNIPD 2007
10
11
Fondamenti Informatica
UNIPD 2007
12
3
Risposte
1.
2.
3.
Gerarchie dell’ereditarietà
due istanze: balance e interestRate
deposit, withdraw, getBalance, e
addInterest.
Manager è la Sottoclasse; Employee è
la Superclasse.
Fondamenti Informatica
UNIPD 2007
13
|
Un insieme di classi può formare una
complessa gerarchia di ereditarietà
Fondamenti Informatica
Gerarchie dell’ereditarietà
es: Swing
UNIPD 2007
14
Gerarchie dell’Ereditarietà
es: gerarchia Swing
Superclasse JComponent ha i metodi
getWidth, getHeight
| La classe AbstractButton ha i metodi
per impostare/prendere testo e icone
|
Fondamenti Informatica
UNIPD 2007
15
Fondamenti Informatica
UNIPD 2007
16
4
Una semplice gerarchia:
es. conto corrente
|
Una semplice gerarchia:
es. conto corrente
Considera una banca che offre ai suoi
clienti i seguenti tipi di conto:
1.
2.
Conto corrente: no interessi; poche
transazioni gratuite al mese, alle
successive transazioni hanno una piccola
spesa
Conto risparmio: si guadagna l’interesse
che viene composto mensilmente
Fondamenti Informatica
UNIPD 2007
17
Fondamenti Informatica
Una semplice gerarchia:
es. conto corrente
Superclasse JComponent ha i metodi
getWidth, getHeight
| La classe AbstractButton ha i metodi
per impostare/prendere testo e icone
UNIPD 2007
18
Una semplice gerarchia:
es. conto corrente
Tutti i conti hanno il metodo getBalance
| Tutti i conti supportano i metodi deposit e
withdraw, ma l’implementazione è diversa
|
Fondamenti Informatica
UNIPD 2007
|
19
|
Al conto corrente serve il metodo
deductFees;
|
Al Conto risparmio serve il metodo
addInterest
Fondamenti Informatica
UNIPD 2007
20
5
Verifica
Risposte
4.
Qual’è lo scopo della classe
JTextComponent in Fig. 4?
5.
Quale istanza dovremo aggiungere alla
classe CheckingAccount?
Fondamenti Informatica
UNIPD 2007
4.
5.
21
Per esprimere il comportamento comune
del campo testo e delle componenti del
testo
Ci serve un contatore che conti il numero
di prelievi e depositi
Fondamenti Informatica
Ereditarietà - metodi
|
Ereditarietà - metodi
Sovrascrivere un metodo:
|
fornire una diversa implementazione del
metodo che esiste nella Superclasse
z Deve avere la stessa firma (stesso nome e
stessi tipi di parametri)
z Se è applicato a un oggetto di tipo
Sottoclasse, il metodo sovrascritto viene
eseguito
UNIPD 2007
Ereditare un metodo:
Non fornire una diversa implementazione
del metodo che esiste nella Superclasse
z Il metodo della Superclasse può venire
applicato all’oggetto Sottoclasse
z
Fondamenti Informatica
22
UNIPD 2007
z
23
Fondamenti Informatica
UNIPD 2007
24
Continued…
6
Ereditarietà - metodi
|
Ereditare campi d’istanza
Aggiungere un metodo:
Non si possono riscrivere campi
| Ereditare campi : tutti i campi della
Superclasse vengono automaticamente
ereditati
| Aggiungere campi: scrivere un nuovo
campo che non esiste nella Superclasse
|
Fornire un nuovo metodo che non esiste
nella Superclasse
z Il nuovo metodo può essere applicato solo
agli oggetti Sottoclasse
z
Fondamenti Informatica
UNIPD 2007
25
Fondamenti Informatica
E se definisci un nuovo campo d’istanza
con lo stesso nome del campo della
Superclasse?
|
UNIPD 2007
sovrascrivere deposit e withdraw per
incrementare il contatore delle transazioni
public class CheckingAccount extends BankAccount
{
public void deposit(double amount) {. . .}
public void withdraw(double amount) {. . .}
public void deductFees() {. . .} // new method
private int transactionCount;
// new instance field
}
Ogni oggetto avrebbe due istanze con lo
stesso nome
z I campi possono avere valori diversi
z Possibile ma estremamente indesiderabile
z
Fondamenti Informatica
26
Implementare la classe
CheckingAccount
Ereditare campi d’istanza
|
UNIPD 2007
27
Fondamenti Informatica
UNIPD 2007
28
7
Implementare la classe
CheckingAccount
|
Implementare la classe
CheckingAccount
Ogni oggetto CheckingAccount ha due
istanze:
|
balance (ereditato da BankAccount)
z transactionCount (nuovo a
CheckingAccount)
getBalance() (ereditato da BankAccount)
z deposit(double amount) (sovrascrive il
metodo di BankAccount)
z withdraw(double amount) (sovrascrive il
metodo di BankAccount)
z deductFees() (nuovo a CheckingAccount)
z
Fondamenti Informatica
UNIPD 2007
Puoi applicare 4 metodi all’oggetto
CheckingAccount:
z
29
Fondamenti Informatica
I campi ereditati sono privati
|
Considera il metodo deposit di
CheckingAccount
UNIPD 2007
30
I campi ereditati sono privati
una Sottoclasse non ha accesso ai campi
privati della sua Superclasse
| la Sottoclasse deve usare l’interfaccia
pubblica
|
public void deposit(double amount) {
transactionCount++;
// now add amount to balance
. . .
}
non può aggiungere amount a balance
| balance è un campo private della
Superclasse
|
Fondamenti Informatica
UNIPD 2007
31
Fondamenti Informatica
UNIPD 2007
32
8
Invocare un metodo
Superclasse
|
Invocare un metodo
Superclasse
Non si può chiamare deposit(amount)
nel metodo deposit di
CheckingAccount
z
Ora chiama il metodo deposito della classe
BankAccount
| Completa il metodo:
|
this.deposit(amount)
Chiamerebbe lo stesso metodo (ricorsione
infinita)
| invece, invoca il metodo della Superclasse
public void deposit(double amount)
{
transactionCount++;
// Now add amount to balance super.deposit(amount);
}
|
z
super.deposit(amount)
Fondamenti Informatica
UNIPD 2007
33
Sintassi 10.2: invocare un
metodo Superclasse
Fondamenti Informatica
UNIPD 2007
34
Implementazione metodi
rimanenti
super.methodName(parameters)
Example:
public void deposit(double amount)
{
transactionCount++;
super.deposit(amount);
}
Purpose:
To call a method of the superclass instead of the method of the current class
Fondamenti Informatica
UNIPD 2007
35
public class CheckingAccount extends BankAccount
{
. . .
public void withdraw(double amount)
{
transactionCount++;
// Now subtract amount from balance
super.withdraw(amount);
}
Fondamenti Informatica
UNIPD 2007
36
9
Implementazione metodi
rimanenti
Verifica
public void deductFees()
{
if (transactionCount > FREE_TRANSACTIONS)
{
double fees = TRANSACTION_FEE
* (transactionCount - FREE_TRANSACTIONS);
super.withdraw(fees);
}
transactionCount = 0;
}
. . .
private static final int FREE_TRANSACTIONS = 3;
private static final double TRANSACTION_FEE = 2.0;
Perchè il metodo withdraw della classe
CheckingAccount chiama
super.withdraw?
Perchè il metodo deductFees imposta il
contatore delle transazioni a zero?
6.
7.
}
Fondamenti Informatica
UNIPD 2007
37
Fondamenti Informatica
UNIPD 2007
38
Errori comuni:
i campi istanza oscuri
Risposte
6.
Gli serve per ridurre il saldo, e non può
accedere al campo balance direttament
|
7.
In modo che il contatore possa riflettere il
numero di transazioni del mese seguente
|
una Sottoclasse non ha accesso al campo
d’istanza privato della Superclasse
Errore del principiante: “risolvere" questo
problema aggiungendo un’altra istanza con lo
stesso nome:
public class CheckingAccount extends BankAccount {
public void deposit(double amount)
{
transactionCount++;
balance = balance + amount;
}
. . .
private double balance; // Don't
Fondamenti Informatica
UNIPD 2007
39
}
Fondamenti Informatica
UNIPD 2007
40
10
Errori comuni:
i campi istanza oscuri
|
Costruttore della Sottoclasse
Ora il metodo deposit compila, ma non
aggiorna il saldo corretto!
|
super segiuto dalle parentesi indica una
chiamata al costruttore della Superclasse
public class CheckingAccount extends BankAccount {
public CheckingAccount(double initialBalance)
{
// Construct superclass
super(initialBalance);
// Initialize transaction count
transactionCount = 0;
}
. . .
}
Fondamenti Informatica
UNIPD 2007
41
Costruttore della Sottoclasse
deve essere la prima istruzione nel
costruttore della Sottoclasse
| se il costruttore della Sottoclasse non
chiama il costruttore della Superclasse,
viene usato il costruttore di default della
Superclasse
|
42
Sintassi 10.1: chiamare il
Costruttore della Sottoclasse
Example:
public CheckingAccount(double initialBalance)
{
super(initialBalance);
transactionCount = 0;
}
costruttore di default Ö senza parametri
z Se tutti i costruttori della Superclasse
richiedono parametri, il compilatore dà
errore
UNIPD 2007
UNIPD 2007
ClassName(parameters)
{
super(parameters);
. . .
}
z
Fondamenti Informatica
Fondamenti Informatica
Purpose:
To invoke a constructor of the superclass. Note that this statement must
be the first statement of the subclass constructor.
43
Fondamenti Informatica
UNIPD 2007
44
11
Verifica
8.
9.
Risposte
Perchè il costruttore SavingsAccount
nella Sezione 13.1 non chiama il
costruttore della Superclasse?
Quando invochi un metodo Superclasse
con la parola-chiave super, la chiamata
deve essere la prima istruzione del
metodo della Sottoclasse?
Fondamenti Informatica
UNIPD 2007
8.
9.
45
Era pronto per usare il costruttore di
default della Superclasse, che setta il
saldo a zero.
No – è un requisito solo dei costruttori. Per
esempio, il metodo
SavingsAccount.deposit prima
incremente il contatore della transazione,
poi chiama il metodo della Superclasse.
Fondamenti Informatica
Conversione di tipo fra
sottoclasse e superclasse
|
|
La superclasse anAccount non conosce tutta la
storia dell’oggetto a cui si riferisce:
anAccount.deposit(1000); // OK
anAccount.addInterest();
// No,non è un metodo della classe a cui appartiene anAccount
|
Quando convertite un oggetto della sottoclasse in
un oggetto di superclasse:
z
z
UNIPD 2007
46
Conversione di tipo fra
sottoclasse e superclasse
I tre riferimenti a oggetti memorizzati in
collegeFund, anAccount, e anObject si
riferiscono tutti allo stesso oggetto di tipo
SavingsAccount
Fondamenti Informatica
UNIPD 2007
47
Il valore di riferimento stesso non cambia: si tratta
dell’indirizzo di memoria che contiene l’oggetto.
Ma,dopo la conversione si hanno minori
informazioni sull’oggetto.
Fondamenti Informatica
UNIPD 2007
48
12
Conversione di tipo fra
sottoclasse e superclasse
|
Conversione di tipo fra
sottoclasse e superclasse
Perchè avere meno informazioni a proposito di un
oggetto?
z
public void transfer(double amount, BankAccount other)
{
withdraw(amount);
other.deposit(amount);
}
|
Potete utilizzare questo metodo per trasferire
denaro da ogni tipo di BankAccount
Fondamenti Informatica
UNIPD 2007
49
Conversione di tipo fra
sottoclasse e superclasse
|
|
Questo cast però può essere pericoloso: se
vi sbagliate viene lanciata un’eccezione
Fondamenti Informatica
UNIPD 2007
50
Esempio:
if (anObject instanceof BankAccount)
{
BankAccount anAccount = (BankAccount) anObject;
. . .
}
if (anObject instanceof BankAccount)
{
BankAccount anAccount = (BankAccount) anObject;
. . .
}
UNIPD 2007
BankAccount anAccount = (BankAccount) anObject;
object instanceof TypeName
testa se l’oggetto appartiene ad un
particolare tipo
Fondamenti Informatica
Può darsi che abbiate bisogno di convertire
un riferimento di superclasse in un
riferimento di sottoclasse
Syntax 10.4: L’operatore
InstanceOf
L’operatore instanceof
z
|
per riutilizzare codice che può elaborare oggetti
della superclasse ma non oggetti della sottoclasse
Obiettivo:
Restituisce true se oggetto è un esemplare di TypeName
(o di uno dei suoi sottotipi); altrimenti restituisce false.
51
Fondamenti Informatica
UNIPD 2007
52
13
Verifica
Risposte
10.
Perchè il secondo parametro del metodo
transfer deve essere di tipo
BankAccount e non, per esempio, di
tipo SavingsAccount?
11.
Perchè non possiamo modificare il
secondo parametro del metodo transfer
in modo che sia di tipo Object?
Fondamenti Informatica
UNIPD 2007
53
10.
Noi vogliamo usare il metodo per tutti I generi
di bank accounts. Noi abbiamo utilizzato un
parametro di tipo SavingsAccount, noi
perciò non possiamo chiamare il metodo con
un oggetto CheckingAccount .
11.
Noi non possiamo invocare il metodo
deposit di una variabile di tipo Object.
Fondamenti Informatica
Polimorfismo
|
UNIPD 2007
54
Polimorfismo
In Java il tipo di una variabile non determina
completamente il tipo dell’oggetto a cui essa
fa riferimento
|
Il compilatore deve controllare che solo i
metodi autorizzati siano stati invocati
BankAccount aBankAccount = new SavingsAccount(1000);
// aBankAccount holds a reference to a SavingsAccount
|
Object anObject = new BankAccount();
anObject.deposit(1000); // Wrong!
Le chiamate al metodo sono determinate dal
tipo reale dell’oggetto, non in base al tipo di
riferimento dell’oggetto
BankAccount anAccount = new CheckingAccount();
anAccount.deposit(1000);
// Calls "deposit" from CheckingAccount
Fondamenti Informatica
UNIPD 2007
55
Fondamenti Informatica
UNIPD 2007
56
14
Polimorfismo
|
Polimorfismo
z
|
AccountTester.java
capacità di riferirsi agli oggetti di vario tipo
variandone il comportamento
Realizzazione di un polimorfismo:
public void transfer(double amount, BankAccount other) {
withdraw(amount); // abbreviazione: this.withdraw(amount)
other.deposit(amount);
}
|
In relazione ai tipi di oggetti, vengono
invocate versioni diverse dei withdraw e
deposit
Fondamenti Informatica
UNIPD 2007
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
57
/**
Questo programma collauda la classe BankAccount e le sue
sottoclassi.
*/
public class AccountTester
{
public static void main(String[] args)
{
SavingsAccount momsSavings
= new SavingsAccount(0.5);
CheckingAccount harrysChecking
= new CheckingAccount(100);
momsSavings.deposit(10000);
Fondamenti Informatica
AccountTester.java
[2]
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34: }
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
momsSavings.transfer(1000, harrysChecking);
harrysChecking.withdraw(400);
// Simulazione della fine del mese
momsSavings.addInterest();
harrysChecking.deductFees();
System.out.println("Mom's savings balance = $“
+ momsSavings.getBalance());
System.out.println("Harry's checking balance = $“
+ harrysChecking.getBalance());
}
UNIPD 2007
58
BankAccount.java
momsSavings.transfer(2000, harrysChecking);
harrysChecking.withdraw(1500);
harrysChecking.withdraw(80);
Fondamenti Informatica
UNIPD 2007
59
/**
Un conto bancario ha un saldo che può essere modificato
con versamenti e prelievi.
*/
public class BankAccount
{
/**
Costruisce un conto bancario con saldo uguale a zero.
*/
public BankAccount()
{
balance = 0;
}
/**
Costruisce un conto bancario con un saldo assegnato.
@param initialBalance il saldo iniziale
*/
Fondamenti Informatica
UNIPD 2007
60
15
BankAccount.java [2]
BankAccount.java [2]
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
public BankAccount(double initialBalance)
{
balance = initialBalance;
}
/**
Versa denaro nel conto bancario.
@param amount la somma da versare
*/
public void deposit(double amount)
{
balance = balance + amount;
}
/**
Preleva denaro dal conto bancario.
@param amount la somma da prelevare
*/
Fondamenti Informatica
UNIPD 2007
61
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
public void withdraw(double amount)
{
balance = balance - amount;
}
/**
Restituisce il valore del saldo del conto bancario.
@return il saldo attuale
*/
public double getBalance()
{
return balance;
}
/**
Trasferisce denaro dal conto a un altro conto
@param amount la somma da trasferire
@param other l’altro conto
*/
Fondamenti Informatica
BankAccount.java [2]
56:
57:
58:
59:
60:
61:
62:
63: }
private double balance;
UNIPD 2007
62
CheckingAccount.java
public void transfer(double amount, BankAccount other)
{
withdraw(amount);
other.deposit(amount);
}
Fondamenti Informatica
UNIPD 2007
63
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
/**
Un conto corrente che addebita commissioni per le
transazioni. */
public class CheckingAccount extends BankAccount
{
/**
Costruisce un conto corrente con un saldo assegnato.
@param initialBalance il saldo iniziale
*/
public CheckingAccount(double initialBalance)
{
// costruisce la superclasse
super(initialBalance);
// azzerra il conteggio delle transazioni
transactionCount = 0;
}
Fondamenti Informatica
UNIPD 2007
64
16
CheckingAccount.java
[2]
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
CheckingAccount.java
[3]
public void deposit(double amount)
{
transactionCount++;
// ora aggiungi amount al saldo
super.deposit(amount);
}
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52: }
public void withdraw(double amount)
{
transactionCount++;
// ora sottrai amount dal saldo
super.withdraw(amount);
}
/**
Sottrae le commissioni accumulate e azzerra il
relativo conteggio.
*/
Fondamenti Informatica
UNIPD 2007
65
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
private int transactionCount;
private static final int FREE_TRANSACTIONS = 3;
private static final double TRANSACTION_FEE = 2.0;
Fondamenti Informatica
UNIPD 2007
66
SavingsAccount.java
[2]
SavingsAccount.java
01:
02:
03:
04:
05:
06:
07:
public void deductFees()
{
if (transactionCount > FREE_TRANSACTIONS)
{
double fees = TRANSACTION_FEE *
(transactionCount - FREE_TRANSACTIONS);
super.withdraw(fees);
}
transactionCount = 0;
}
/**
Un conto bancario che matura interessi a un tasso fisso.
*/
public class SavingsAccount extends BankAccount
{
/**
Costruisce un conto bancario con un tasso di
interesse assegnato.
@param rate il tasso di interesse
*/
public SavingsAccount(double rate)
{
interestRate = rate;
}
18:
19:
20:
21:
22:
23:
24:
25: }
public void addInterest()
{
double interest = getBalance() * interestRate / 100;
deposit(interest);
}
private double interestRate;
/**
aggiunge al saldo del conto gli interessi maturati.
*/
Fondamenti Informatica
UNIPD 2007
67
Fondamenti Informatica
UNIPD 2007
68
17
SavingsAccount.java
[3]
Verifica
Visualizza:
Se a è una variabile di tipo
BankAccount che contiene un
riferimento non nullo, che informazioni
abbiamo in merito all’oggetto a cui si
riferisce?
Se a si riferisce a un conto corrente, che
effetto ha l’invocazione seguente?
a.transfer(1000, a)
12.
Mom's savings balance = $7035.0
Harry's checking balance = $1116.0
13.
Fondamenti Informatica
UNIPD 2007
69
Fondamenti Informatica
Risposte
12.
13.
UNIPD 2007
70
Controllo di accesso
L’oggetto è un’istanza di BankAccount o
di una delle sue sottoclassi.
Il bilancio di a è invariato, e la transazione
count viene incrementata due volte.
|
Java fornisce quattro livelli per il controllo di
accesso a variabili, metodi e classi:
z
public access
• Accesso dai metodi di tutte le classi
z
private access
• Accesso solamente mediante i metodi della loro
classe specifica
z
protected access
• Accesso dai metodi di tutte le sottoclassi
Argomenti avanzati 10.3
Fondamenti Informatica
UNIPD 2007
71
Fondamenti Informatica
UNIPD 2007
72
18
Livelli di accesso
raccomandato
Controllo di accesso
|
package access
|
Default in assenza di un modificatore di
accesso
z Si può accedere da tutte le classi dello
stesso pacchetto
z Buona impostazione per le classi, ma
estremamente infelice per i campi
z
Fondamenti Informatica
UNIPD 2007
Variabili di istanza e campi static: sono sempre
private.
Eccetto:
z
z
z
73
Fondamenti Informatica
Livelli di accesso
raccomandato
Metodi: public o private
| Classi o interfacce: public o package
La migliore alternativa al package access
(accesso di pacchetto): inner classes (classi
interne)
• In generale, l’inner classes (classi interne) non può
essere pubblica (esiste qualche eccezione, ad
es.Ellipse2D.Double)
|
Bisogna stare attenti ad utilizzare i metodi con
il package access (generalmente i metodi
dovrebbero essere public o private) 75
Fondamenti Informatica
UNIPD 2007
UNIPD 2007
74
Verifica
|
z
Le costanti pubbliche(public static final) sono utili e
sicure.
Qualche oggetto, come System.out, ha bisogno di
essere accessibile a tutti i programmi (public)
In rare occasioni, alcune classi in un pacchetto
devono cooperare molto strettamente;può essere
utile fornire ad alcune variabili il package
access(accesso di pacchetto). Tuttavia le inner
classes( classi interne) sono la soluzione migliore.
14.
15.
Quale è una comune motivzione che
porta alla definizione di campi di
esemplare con package access(accesso
di pacchetto)?
Se una classe dotata di costruttore
pubblico ha il package access, che ne
può costruire esemplari?
Fondamenti Informatica
UNIPD 2007
76
19
Object:La superclasse
universale
Risposte
Accidentalmente si dimentica il
modificatore private.
Qualsiasi metodo di classe nello stesso
pacchetto.
14.
15.
Fondamenti Informatica
UNIPD 2007
| Tutte
le classi estendono
automaticamente la classe Object
77
Fondamenti Informatica
Object:La superclasse
universale
|
z
z
|
78
Sovrascrivere il metodo
toString
I metodi più utilizzati:
z
UNIPD 2007
Restituisce una stringa per ciascun oggetto
| Utile per trovare errori logici:
|
String toString()
boolean equals(Object otherObject)
Object clone()
Rectangle box = new Rectangle(5, 10, 20, 30);
String s = box.toString();
// Sets s to "java.awt.Rectangle[x=5,y=10,width=20,height=30]"
Una buona idea è quella di sovrascrivere
questi metodi nelle vostre classi
Fondamenti Informatica
UNIPD 2007
79
Fondamenti Informatica
UNIPD 2007
80
20
Sovrascrivere il metodo
toString
|
Sovrascrivere il metodo
toString
toString chiamato tutte le volte che
concatenate una stringa con un oggetto.
|
"box=" + box;
// risulta: "box=java.awt.Rectangle[x=5,y=10,width=20,height=30]"
|
public String toString()
{
return "BankAccount[balance=" + balance + "]";
}
Object.toString stampa il nome della
classe seguito dal codice hash dell’oggetto
|
BankAccount momsSavings = new BankAccount(5000);
String s = momsSavings.toString();
// s si riferisce a qualcosa di simile a
UNIPD 2007
81
Fondamenti Informatica
Sovrascrivere il metodo
equals
|
|
UNIPD 2007
UNIPD 2007
82
Sovrascrivere il metodo
equals
equals confronta
il contenuto di due
oggetti:
Fondamenti Informatica
Questo sistema funziona meglio:
BankAccount momsSavings = new BankAccount(5000);
String s = momsSavings.toString();
// s si riferisce alla stringa "BankAccount[balance=5000]"
"BankAccount@d24606bf"
Fondamenti Informatica
Per una informazione migliore dell’oggetto,
si sovrascrive il metodo toString:
83
L’opeatore == verifica se due riferimenti
puntano allo stesso oggetto:
Fondamenti Informatica
UNIPD 2007
84
21
Sovrascrivere il metodo
equals
| Definite il metodo equals per verificare se due
Sovrascrivere il metodo
equals
oggetti hanno lo stesso stato.
| Quando ridefinite il metodo, non vi è permesso
modificare la firma del metodo stesso, dovete
eseguire un cast sul parametro:
|
Dovreste sovrascrivere anche il metodo
hashCode, in modo che oggetti uguali
abbiano lo stesso codice hash.
public class Coin
{
. . .
public boolean equals(Object otherObject)
{
Coin other = (Coin) otherObject;
return name.equals(other.name) && value == other.value;
}
. . . }
Fondamenti Informatica
UNIPD 2007
85
Fondamenti Informatica
Verifica
16.
17.
86
Risposte
L’invocazione x.equals(x) deve
sempre restituire true?
Si può realizzare il metodo equals
usando il metodo toString? E’ una
cosa consigliabile?
Fondamenti Informatica
UNIPD 2007
UNIPD 2007
16.
17.
87
Certo,a meno che x non sia null.
Se al metodo toString ritorna una
stringa che descriva tutte le istanze, si
invoca semplicemente il metodo
toString nei parametri impliciti ed
espliciti, e appare il risultato. Tuttavia,
confrontare i campi di un oggetto risulta
più efficiente di convertirli in stringhe.
Fondamenti Informatica
UNIPD 2007
88
22
Sovrascrivere il metodo
clone
|
Sovrascrivere il metodo
clone
La copia di un riferimento a un oggetto
fornisce semplicemente due riferimenti allo
stesso oggetto
|
Creare copia
oggetto
BankAccount account2 = account;
Fondamenti Informatica
UNIPD 2007
89
Fondamenti Informatica
Sovrascrivere il metodo
clone
UNIPD 2007
90
Il metodo Object.clone
Definire il metodo clone significa realizzare
un nuovo oggetto
| Come invocare il metodo clone:
|
|
Crea sotto copie
BankAccount clonedAccount = (BankAccount) account.clone();
|
Deve restituire un valore perché è di tipo
Object
Fondamenti Informatica
UNIPD 2007
91
Fondamenti Informatica
UNIPD 2007
92
23
Il metodo Object.clone
Non clona automaticamente tutti i sottooggetti
| Il metodo viene dichiarato protected;
questo vi impedisce di chamare
x.clone() se la classe a cui appartiene x
non ha ridefinito clone come metodo
public
| Bisogna sovrascrivere il metodo clone con
cura
|
Fondamenti Informatica
UNIPD 2007
93
24