Ciò che non riesci a comprendere è esattamente l'effetto del polimorfismo.Originariamente inviato da sigfrid_xxxx
Allora, la cosa che non capisco è questa. con l'istruzione Animale a= new Cane() io creo un oggetto di tipo Cane e lo memorizzo in un oggetto di tipo animale. Quindi dovrei fare il cosiddetto upcasting. Quindi, siccome a è di tipo Animale, dovrebbe richiamare il metodo interroga della classe Animale. Ma in realtà a chiama interroga della classe Cane, stampando a video "Bau",ma perchè?
Tu hai una variabile di tipo Animale che, potenzialmente, può riferirsi ad istanze della classe Animale stessa o di classi discendenti; tuttavia, benché il riferimento sia di tipo Animale, l'oggetto vero e proprio appartiene alla classe Cane, ed è proprio per questo motivo che Java segue l'implementazione del metodo invocato di questa classe.
A runtime, quando il metodo viene invocato, il tipo di oggetto con cui si ha a che fare viene verificato; trattandosi di un oggetto di tipo Cane, è l'implementazione di questa classe ad essere invocata.
Questo consente di memorizzare nel riferimento qualsiasi oggetto sia di tipo Animale o appartenente ad una classe discendente e, invocando un metodo, ottenere l'esecuzione dell'implementazione specifica fornita dalla classe di appartenenza.
Avere una variabile o un parametro che appartiene alla classe base significa poter passare a quell'identificatore un riferimento ad un oggetto che appartiene a tale classe o a una delle sue discendenti, indifferentemente. Ma nel caso di metodi non "chiusi", ciascuna classe può ridefinire il loro comportamento per personalizzarlo.Originariamente inviato da sigfrid_xxxx
Allora che differenza c'è con lo scrivere Cane a = new Cane()? Questa cosa davvero non riesco a capirla. Io pensavo che facendo l'upcasting, si perdesse tutte le implementazioni fatte nella classe figlia. Ma in realtà non si perdono.
Forse questa lezione può essere più chiara ed illustrativa.
Supponi di avere una classe che contiene i dati di una persona, inclusa l'età. Essa deve logicamente essere maggiore di zero; supponendo di memorizzarla in un campo intero e rendere quest'ultimo pubblico, qualsiasi oggetto faccia uso di un'istanza di questa classe, può accedere direttamente al campo e memorizzare un valore che potrebbe non essere valido, ad esempio -1. L'uso di metodi get e set consente di regolare l'accesso a questi campi, che rappresentano lo stato complessivo del tuo oggetto, e garantire che tale stato rimanga consistente, nel caso specifico impedendo all'oggetto "client" che utilizza l'istanza di memorizzare un valore negativo per l'età, inserendo il controllo della validità del valore da impostare nel metodo di set, generando un'eccezione in caso di errore oppure lasciando il valore precedentemente memorizzato.Originariamente inviato da sigfrid_xxxx
Altra cosa che non ho capito è l'incapsulamento. Cioè, cosa cambia se alle variabili di una classe non ci accedo direttamente ma mediante dei metodi getters e setters? Mi fareste un breve esempio in cui è pericoloso non usare l'incapsulamento? Grazie![]()
Un altro uso dei metodi getter e setter è la possibilità di generare effetti collaterali; ad esempio, un controllo visuale potrebbe disporre di un metodo setBackground che imposta il valore di un campo privato memorizzando il colore passato come parametro al metodo di set e, inoltre, provocare il ridisegno del controllo sullo schermo (poiché il colore di sfondo è cambiato).
Ciao!![]()