![]() ![]() |
|
![]() ![]() |
Diagramma di classi:
Si osservi come, grazie all'ereditarietà, le informazioni comuni delle classi Studente e Professore sono fattorizzate nella classe Persona, da cui Studente e Professore ereditano.
![]() ![]() |
|
![]() ![]() |
La definizione di sottoclassi può essere
iterata a piacere: si possono definire delle gerarchie di classi arbitrariamente complesse.
In Java ogni classe è una classe derivata, in modo diretto o indiretto, dalla classe Object. Infatti, ciascuna classe che non estende un'altra classe estende automaticamente la classe Object.
![]() |
![]() ![]() |
|
![]() ![]() |
La classe Object è la superclasse, diretta o indiretta, di ciascuna classe in Java.
Grazie al meccanismo dell'ereditarietà, i suoi metodi possono essere invocati su tutti gli oggetti. Descrizione completa della classe Object: [locale, Medialab, Sun] In particolare, alcuni metodi molto utili sono:
|
![]() ![]() |
|
![]() ![]() |
Il metodo toString()
restituisce una stringa che può essere considerata come la
"rappresentazione
testuale" dell'oggetto su cui è invocato (da usare ad esempio
nella stampa).
La definizione default del metodo nella classe Object restituisce una stringa del tipo
Il metodo deve quindi essere ridefinito in ogni classe che lo usa, per ottenere un risultato significativo. Tipicamente, di un oggetto si vogliono stampare i valori delle variabili d'istanza, ed eventualmente una intestazione. Grazie all'esistenza del metodo toString(), in Java possiamo liberamente mettere una variabile di tipo riferimento in un contesto in cui ci dovrebbe essere una stringa (ad esempio in un comando di stampa, oppure come argomento dell'operatore di concatenazione +): l'oggetto verrà convertito in una stringa automaticamente invocando su di esso il metodo toString(). Il codice:
è compilato correttamente. Il compilatore invoca automaticamente il metodo toString() su box, perché sa che ciascun oggetto ha questo metodo, dal momento che ogni classe estende la classe Object, che a sua volta definisce toString(). Si provi ad eseguire la classe PrintBankAccount che stampa un oggetto della classe BankAccount. Poi si compili BankAccount1 (che aggiunge il metodo toString() riportato sotto), e si esegua PrintBankAccount1.
|
![]() ![]() |
|
![]() ![]() |
Come descritto nella documentazione della classe Object:
[locale,
Medialab,
Sun],
il metodo equals deve
implementare una relazione
d'equivalenza sulle istanze di ogni classe, cioè
una relazione riflessiva,
simmetrica e
transitiva (e deve soddisfare
alcune altre proprietà).
Nella pratica, il metodo equals di una classe viene scritto in modo che l'invocazione <obj1>.equals(<obj2>) restituisce true quando gli oggetti <obj1> e <obj2> sono istanze della stessa classe e hanno uguale contenuto, cioè valori equivalenti per ogni variabile d'istanza. Ad esempio, come abbiamo visto, due oggetti della classe String sono equals se sono costituiti dalla stessa sequenza di caratteri. Nella classe Object, poichè non si può fare alcuna assunzione sulla struttura interna degli oggetti su cui viene invocato, il metodo equals è realizzato nel modo più restrittivo possibile: due oggetti sono considerati equivalenti solo se sono lo stesso oggetto. Quindi il confronto è basato sull'operatore ==. Poichè tutte le classi ereditano da Object, il metodo equals può essere invocato su una istanza di una qualunque classe. Se però nella classe in questione il metodo non è stato sovrascritto, verrà eseguito il metodo ereditato da Object, con risultati che potrebbero essere inattesi. Quindi il metodo equals deve essere ridefinito in tutte le classi in cui è necessario effettuare confronti, per ottenere risultati significativi.
Osservazione:
|
![]() ![]() |
|
![]() ![]() |
Estendiamo le classi Persona,
Studente e Professore
sovrascrivendo il metodo equals
della classe Object.
|