Se proviamo nuovamente a compilare il sorgente della classe UomoDAffari,
otterremo il seguente errore:
che non ci dovrebbe stupire più di tanto: lattributo nome
dichiarato allinterno della classe Uomo è ad accesso
privato, il che vuol dire, come abbiamo visto in precedenza, che
nessuna classe esterna la può utilizzare direttamente.
Potremmo pensare di dichiararla ad accesso pubblico o di omettere
il modificatore di accesso.
Queste soluzioni funzionano ma non sono esattamente quello che vorremmo,
perché è nostra intenzione proteggere questo attributo da azioni
esterne indesiderate.
La soluzione adeguata per questo problema è il modificatore di accesso
protected, che ha pressappoco la stessa funzione di private,
ma permette alle classi derivate di accedere a quellattributo:
proprio quello che cercavamo!
Se modifichiamo il codice della classe Uomo, sostituendo
al modificatore private nella dichiarazione della variabile
nome il modificatore protected, e proviamo a ricompilare,
non sarà più segnalato alcun errore.
Allinterno del corpo della classe UomoDAffari
è stato definito un metodo già presente nella classe Uomo,
ossia:
public void dice(String
parole) {
System.out.println(titoloDiStudio + ' ' + nome + ":
- " + parole);
}
Questa operazione prende il nome di ridefinizione di un metodo
e serve per specializzare il comportamento di una classe figlio
rispetto alla classe padre.
Infatti, quando viene invocato un metodo su una classe, linterprete
Java cerca la dichiarazione del metodo dapprima nel corpo della
classe, se la trova la esegue, altrimenti risale la gerarchia di
figlio in padre, finchè non trova una dichiarazione del metodo (ovviamente
se la ricerca è infruttuosa viene rilevato un errore).
Tutto ciò è possibile grazie al fatto che ogni classe può avere
al massimo una sola superclasse, per cui non esiste ambiguità nella
ricerca del metodo.
In questo Java differisce da C++, nel quale è permessa lereditarietà
multipla, cioè la possibilità di derivare attributi e metodi da
più superclassi: sebbene rappresenti una buona possibilità di programmazione,
lereditarietà multipla può portare a situazioni di ambiguità.
Supponiamo di definire una classe GiocatoreDiGolf nel
seguente modo:
class GiocatoreDiGolf {
...
public void dice(String parole) {}
...
}
Se fosse possibile ereditare da più classi, potremmo decidere di
far derivare UomoDAffariRicco sia da Uomo
che da GiocatoreDiGolf e di non ridefinire il metodo
dice.
Nel momento in cui invocassimo tale metodo su un oggetto di tipo
UomoDAffariRicco, non potremmo sapere con certezza se
venisse eseguito il metodo definito nella classe Uomo
o quello definito nella classe GiocatoreDiGolf.
Per ovviare a casi di ambiguità di tale tipo Java permette che
una classe erediti solo da unaltra classe.
Questa soluzione elimina ogni causa di ambiguità al riguardo, ma
si rivela troppo limitativa per sviluppare gerarchie di una certa
complessità, che sono utili in gran parte delle applicazioni più
comuni.
Per ovviare a un limite troppo stretto, Java permette di utilizzare
le interfacce, ossia delle classi i cui metodi non eseguono
alcuna istruzione.
Lavorare con le interfacce è come lavorare con le classi, senonché
non è possibile creare direttamente unistanza di uninterfaccia
mediante listruzione new.
E possibile sia utilizzare interfacce nelle nostre classi,
che definirne di nuove.
Per poter utilizzare uninterfaccia occorre utilizzare la parola
chiave implements come parte della definizione di classe,
ad es.
class UomoDAffari extends
Uomo implements unaInterfaccia {
...
}
In questo esempio la classe UomoDAffari eredita gli
attributi e i metodi della classe Uomo e quelli dellinterfaccia
unaInterfaccia.
Poiché le interfacce forniscono solo le definizioni dei metodi,
occorre implementare tali metodi nella propria classe, eliminando
così la possibilità di casi ambigui, propria dellereditarietà
multipla.
Inoltre non cè limite al numero di interfacce che si possono
utilizzare, ma esiste lobbligo di implementare tutti i metodi
di ognuna di esse.
Largomento delle interfacce può essere compreso appieno dopo
aver acquisito una maggiore esperienza con la programmazione orientata
agli oggetti di Java, per cui ne rimandiamo la trattazione completa
alle lezioni successive.
Torna all'indice Generale del corso di Corso di Java di Software Planet