Questo caso in cui viene evidenziata la potenza dell'ereditarietà e del polimorfismo risulta evidente in tutti quei casi in cui non puoi far supposizioni sul tipo preciso di oggetto con cui hai a che fare. Ti dico subito che una cosa del genere
codice:
GreenBox x = new RedBox();
non si usa, in pratica, mai. Questo è il classico esempio didattico. Il vero utilizzo dell'ereditarietà avviene quando non sai a priori quale tipo di oggetto stai usando. Prendiamo l'esempio di un metodo che deve visualizzare l'area di una figura geometrica. Questo metodo prende come parametro un oggetto di tipo Figura (classe madre di altre sottoclassi più specifiche).
Questo metodo non sa con quale tipo di oggetto lavorerà: gli verrà passato un Triangolo? Un Quadrato? Un Trapezio? Un Cercio? Boh... lui non lo sa, però sa che di sicuro gli sarà passata una Figura, perchè tutte le classi menzionate prima estendono tale classe.
La parte più bella e più potente, poi, stà nel polimorfismo: quel metodo deve visualizzare l'area dell'oggetto passato. Ora, un triangolo ha una sua formula per il calcolo dell'area che è nettamente differente dalla formula per il calcolo dell'area di un cerchio, diversa da quella di un Trapezio, e così via... come si procede, quindi? Semplice: tutte le classi prevederanno un metodo calcola(). Ognuna lo implementerà coerentemente, ma sarà il sistema a tempo d'esecuzione preoccuparsi di richiamare quello corretto. Se la Figura passata sarà un Triangolo, richiamerà il metodo calcola() della classe Triangolo, se sarà un Cerchio, richiamerà quela del Cerchio, e così via.
Forse un esempio aiuta a capire:
codice:
// Definisco la classe madre: tutte le altre estendono questa
public abstract class Figura {
public int calcola();
}
// Questa sarà la classe Triangolo (a grandi linee)
public class Triangolo extends Figura {
...
public int calcola() {
return (base * altezza) / 2;
}
...
}
// Classe Cerchio...
public class Cerchio extends Figura {
...
public int calcola() {
return (r * r) * Math.PI;
}
...
}
...
Bene... ora vediamo come si comporta in esecuzione:
codice:
public class Aree {
public static void main(String [] a) {
Triangolo t = new Triangolo();
... // Definisco il mio triangolo
Cerchio c = new Cerchio();
... // Definisco il cerchio
...
visualizzaArea(t);
visualizzaArea(c);
}
public static void visualizzaArea(Figura f) {
System.out.println( f.calcola() );
}
}
Come puoi vedere, nel metodo visualizzaArea io non mi preoccupo affatto del tipo di figura che mi viene passato, tanto non mi importa: so che mi verrà passata una Figura, che possiede un metodo calcola(). Non devo fare altro che richiamarlo.
Spero che come esempio sia stato abbastanza semplice e chiaro. Per altre delucidazioni sono sempre qui.
Ciao.