Buongiorno a tutti,
ho iniziato da poco lo studio del Java, e sto affrontando vari aspetti del polimorfismo, soprattutto l'assegnazione di reference, il casting e i metodi virtuali.
Ho creato, a scopo di esercizio, due classi: "Punto", che astrae un punto nello spazio bidimensionale, e "Punto3D" che astrae un punto nello spazio tridimensionale ed è estensione di "Punto". I metodi sono i soliti get e set, due costruttori (con e senza parametri), e un metodo "info" per la stampa a video delle proprietà. Quest'ultimo metodo, definito in "Punto", viene ridefinito nella sottoclasse "Punto3D".
Infine c'è la terza classe che mi serve per eseguire i test, e questo è il codice
Il mio scopo era quello di provare a capire meglio come funziona il fatto di assegnare un reference di una superclasse all'istanza di una sottoclasse, e poi eseguire il casting sul reference per utilizzare i metodi definiti per la prima volta nella sottoclasse (cosa altrimenti impossibile).codice:public class provaPunti { public static void main(String args[]) { Punto p2D = new Punto3D(10.0F,10.0F,0); Punto3D p3D = new Punto3D(); System.out.println(p2D.info()); p3D = (Punto3D) p2D; p3D.setZ(10.0F); System.out.println(p2D.info()); System.out.println(p3D.info()); } }
Come prima cosa ho notato che sebbene il reference p2D si riferisca ad un oggetto "Punto", in realtà utilizza l'interfaccia pubblica della classe Punto3D, quindi devo utilizzare il costruttore che setta anche la dimensione sull'asse Z... mi chiedo se sia "elegante" definire, nella sottoclasse, un override del costruttore della superclasse. In questo modo potrei definire un punto. A funzionare funziona, ma mi chiedo quanto sia nella filosofia OOP.
Seconda cosa: pensavo che l'istruzione p2D.info() mi avrebbe restituito le informazioni del reference come punto bidimensionale, invece ho visto che richiama il metodo in override, e non quello definito nella superclasse... riprendendo la definizione di metodo virtuale: "un metodo m si definisce virtuale quando è definito in una classe A, ridefinito in una sottoclasse B e invocato su un'istanza di B tramite un reference di A". Ok, questo mi chiarisce le idee... ma allora se assegno il reference alla superclasse attraverso l'istanza della sottoclasse, come faccio a invocare effettivamente il metodo definito nella superclasse e non il suo override? Insomma vorrei che l'istruzione p2D.info() mi dica che ho istanziato un punto bidimensionale, ma così mi dice - giustamente - che ho istanziato un punto tridimensionale.
Terza cosa (la più grave, dato che non capisco proprio come mai succeda): l'istruzione p3D.setZ(10.0F) mi modifica anche la proprietà di p2D... in pratica le ultime due istruzioni mi restituiscono lo STESSO IDENTICO output... capisco che l'interfaccia è quella della classe "Punto3D", ma se il metodo setZ è invocato sul p3D, non capisco come faccia ad andare a modificare anche p2D, che a conti fatti è comunque un'altra variabile!
Grazie a chiunque voglia illuminarmi!
Davide.
EDIT: come al solito, mettere le cose nero su bianco aiuta a fare un po' di luce... Ho capito il perché del terzo punto: l'istruzione p3D = (Punto3D) p2D assegna a p3D lo stesso indirizzo di p2D e ne modifica l'intervallo di puntamento, quindi a questo punto il programma non riesce più a riconoscere la differenza tra i due reference. Capisco che in ottica di programmazione tutto ciò non ha molto senso, ma si tratta di una cosa a scopo puramente didattico.
Se volessi continuare su questa linea ed evitare di far confondere il programma, più che assegnare lo stesso indirizzo mi viene da pensare che dovrei realizzare un metodo che copia i valori... suggerimenti?
Grazie ancora.

Rispondi quotando