Originariamente inviato da perseoclub
Ancora sono un po' confuso! Devo entrare nel meccanismo di questi passaggi logici della OOP e dei casting.
La cosa che mi risulta ancora difficile da digerire è il perché Java è stato concepito per obbligarmi a dichiarare un casting esplicito e non per utilizzare direttamente un fe.getSource().setBackground?
Decisamente mi sto perdendo qualche passaggio fondamentale!
Il problema non è Java (tutti i linguaggi ObjectOriented funzionano così... ed è perfettamente logico).
Torniamo per un attimo all'esempio delle figure.
Un po' di codice:
codice:
public void lavoraConLaFigura(Figura f) {
// Che figura mi è stata passata? Boh...
}
Se tu hai un oggetto Figura (e non sai nient'altro) che puoi fare? Ben poco... perchè non sai che figura sia (concretamente). Non puoi richiamare un metodo per ottenere il raggio di tale figura, perchè non puoi sapere se la figura è effettivamente un cerchio oppure un triangolo oppure ancora un rettangolo (i triangoli, come i rettangoli, non hanno un raggio, ma sono comunque figure!!).
Io al metodo qui sopra posso passare qualunque figura:
codice:
Triangolo t = new Triangolo();
Rettangolo r = new Rettangolo();
Cerchio c = new Cerchio();
lavoraConLaFigura( t );
lavoraConLaFigura( r );
lavoraConLaFigura( c );
Ma lui non sa che figura gli sto passando in un determinato momento... quindi, sapendo che è comunque una Figura, lui può usare tutti i metodi che tale classe mette a disposizione.
Se vuole usare il raggio del cerchio che gli ho passato alla terza chiamata, così com'è non può farlo... anche se ne avrebbe facoltà (perchè in concreto io gli sto dando in pasto un cerchio).
Come si risolve? Con il cast esplicito (previo controllo, chiaramente). Il cast esplicito serve, appunto, a poter lavorare con il tipo preciso dell'oggetto passato:
codice:
public void lavoraConLaFigura(Figura f) {
// Che figura mi è stata passata? Boh... controlliamo
if (f instanceof Rettangolo) {
Rettangolo r = (Rettangolo) f; // E' un rettangolo... potrò farci qualcosa
}
if (f instanceof Triangolo) {
Triangolo t = (Triangolo f; // E' un triangolo... potrò farci qualcos'altro
}
if (f instanceof Cerchio) {
Cerchio c = (Cerchio) f; // E' un cerchio... posso ottenerne il raggio
}
}
Questa si chiama ereditarietà: tramite l'ereditarietà una classe eredita tutto ciò che la classe base (Figura) mette a disposizione, ma in più estende le sue proprietà e i suoi comportamenti, facendogli fare qualcosa in più o qualcosa di più specifico (tralasciando per il momento il polimorfismo, per evitare troppa confusione).
Questo non è un limite di Java: è un limite ovvio e insormontabile di qualunque linguaggio. Se in un certo punto io sto lavorando con qualcosa di generico, non posso fare altro che invocare su quell'oggetto i metodi che la classe generica mette a disposizione (perchè non posso sapere a priori che avrò a che fare con un tipo specifico piuttosto che un altro).
Ciao.