Questa parte mi è chiara, ma grazie per l'approfondimento/riepilogo.
Il mio dubbio è sulla possibilità di gestire i contenuti degli oggetti dopo questi passaggi.
Esempio sensato: se Persona ha un certo metodo mangia() (concreto, non astratto), ovviamente comune alle sottoclassi Studente e Atleta dove però viene overridden (perché fanno attività diverse e quindi seguono diete diverse), scrivendo
codice:
Persona p = new Studente();
Studente s = (Studente) p;
Persona q = new Atleta();
Atleta a = (Atleta) q;
ho perso ogni riferimento al metodo mangia() di Persona (come sto verificando) o posso ancora invocarlo in qualche modo che non conosco e che quindi non so applicare?
Tutto è nato da un esempio, probabilmente sbagliato dato che l'esecuzione viene lasciata al lettore, nel quale si pretendeva di invocare uno stesso metodo in maniera "incrociata" prima tramite upcasting e poi, alternativamente e non successivamente, downcasting.