L’EREDITARIETA’ IN JAVA

SUPER E I MEMBRI DELLE SUPERCLASSI

java-logo

super, oltre all’utilizzo che abbiamo visto nei costruttori, può essere usato anche per accedere ai membri di una superclasse da una sottoclasse. In questi esempi solo per fini dimostrativi useremo attributi non privati nelle classi. Ricorda gli attributi devono avere sempre il modificatore private in modo da essere accessibili solo all’interno della classe in cui sono dichiarati. Vediamo una nuova versione di AClass.

Definizione AClass

LE CLASSI ACLASS E BCLASS

Abbiamo reso di nuovo gli attributi non privati, tra poco capirai il perché. Vediamo la modifica alla sottoclasse.

Definizione BClass

Abbiamo ridefinito l’attributo st, stesso tipo e stesso nome di quello presente nella superclasse. Di fatto ridefinendo tale attributo, BClass nasconde la variabile di livello superiore. Vediamo la classe di test.

Classe di test

Quando creiamo l’istanza di BClass vengono invocati rispettivamente, il costruttore della superclasse e quello della sottoclasse. Il metodo viewAttr() che invochiamo tramite l’istanza bc, visualizza correttamente l’attributo st della superclasse, quando arriviamo al metodo println l’attributo st invocato è quello della sottoclasse.

Classe di Test

Ti starai chiedendo, cosa c’entra la keyword super in tutto questo? Vediamo cosa succede usando super per accedere all’attributo st della superclasse dalla sottoclasse. La chiamata a super non è limitata solo nel costruttore, ma lo possiamo usare in qualsiasi altro metodo.

keyword super

Vediamo la classe di test.

chiamata tramite super alla superclasse

GERARCHIA DI EREDITARIETA’

Negli esempi che abbiamo visto, la nostra strategia di generalizzazione si è fermata a un solo livello. Vediamo la figura sotto riportata.

gerarchia di classi

Abbiamo definito una gerarchia di ereditarietà, CClass è la sottoclasse di BClass mentre la stessa BClass ora è sia sottoclasse che superclasse.

gerarchia di ereditarietà

Ti ricordo che nel costruttore di BClass dobbiamo invocare con la prima istruzione il costruttore della superclasse AClass passandole l’argomento di tipo String a perché è ciò che il costruttore si attende. Introduciamo CClass e analizziamo il codice.

definizione di CClass

CClass ha un costruttore che prende tre parametri, viene chiamato super con due parametri a e b che servono per inizializzare gli attributi di livello superiore a per AClass, b per BClass. Con il parametro c si inizializza l’attributo di istanza di CClass. Abbiamo accesso agli attributi di AClass e BClass perché ricordiamolo non sono private. Vediamo la classe di test.

Test CClass

VARIABILI, REFERENCE, EREDITARIETA’

Definiamo due metodi, uno nella superclasse e uno nella sottoclasse.

Metodi di AClass e BClass

Vediamo la classe di test.

main

Se noi adesso proviamo a fare l’assegnazione b=a cioè assegniamo a b il riferimento della superclasse otteniamo un errore del compilatore.

Errore del compilatore

Se facciamo il contrario a=b questa volta non abbiamo nessun problema.

Assegnamento di reference

Proviamo con la variabile di istanza della superclasse a chiamare il metodo di BClass. Otteniamo ancora un errore.

Errore del compilatore

Questo significa che anche se la superclasse ha lo stesso reference della sottoclasse essa non può accedervi in quanto può accedere solo ai propri membri. Vediamo di riepilogare quello visto sinora e ricavarne una regola generale. Abbiamo due variabili a e b di tipo AClass e BClass che puntano a oggetti delle medesime classi. All’inizio abbiamo questa situazione (vedi figura).

Situazione dei reference Iniziale

Poi abbiamo posto b = a e abbiamo visto che non è possibile assegnare la variabile b a un oggetto della superclasse. (vedi figura)

Assegnamento di reference

Poi abbiamo scambiato i reference e abbiamo visto che è possibile assegnare una variabile della superclasse a un oggetto della sua sottoclasse. Però anche facendo questo la variabile a della superclasse continua a vedere l’oggetto AClass.

Assegnamento di reference

Questo ci porta a questa conclusione finale. È solamente il tipo della variabile cioè il reference type che determina quali membri possono essere acceduti tramite questa variabile, mentre il tipo di oggetto è ininfluente. Questo significa che una volta che la variabile a è stata definita di tipo AClass anche se le assegniamo un oggetto creato come istanza di BClass, questo oggetto viene visto però come oggetto di tipo AClass quindi possiamo accedere ai soli membri definiti nella superclasse.

Conclusioni
Conclusioni

LINK AI POST PRECEDENTI

IL LINGUAGGIO JAVA

LINK AL CODICE SU GITHUB

GITHUB

ESECUZIONE DEL CODICE DI ESEMPIO

  • Scaricare il codice da GITHUB, lanciare il file JAR con il seguente comando in Visual Studio Code, posizionandosi nella directory contenente il JAR.

        java -jar –enable-preview CorsoJava.jar

  • Oppure mettere in esecuzione il main che si trova nel file CorsoJava.java.