A dire il vero il concetto di polimorfismo va piu' in la di quanto avete fin'ora espresso. Questo perche' gli esempi fatti consideravano un solo stadio di discendenza dalla classe base.
Considerate, tuttavia, una classe superiore, che chiamo parent, dalla quale faccio derivare tre classi distinte: child1, child2 e child3.
Nella classe parent esiste un metodo chiamato doSomething() non necessarriamente astratto. A loro volta le tre classi derivate ridefiniscono lo stesso metodo, ognuna in modo diverso dalle altre.
Ora durante l'esecuzione del programma io posso avere un riferimento ad un oggetto di tipo parent. Essendo le tre classi derivate una sottoclasse di parent, le loro istanze possono essere considerate oggetti di tipo parent a tutti gli effetti, di conseguenza il riferimento di cui parlavo prima puo' venire utilizzato anche per le sottoclassi child1, child2, e child3.
Durante l'esecuzione so che posso invocare il metodo doSomething() sul riferimento in mio possesso e so che verra' eseguito il metodo relativo alla classe alla quale mi sto riferendo: quindi se ho una classe child2 la chiamata parent.doSomething() eseguira' proprio il metodo doSomething() come ridefinito nella classe child2. Se invece il riferimento punta a un oggetto di tipo child3 verra' chiamato il metodo della classe child3, senza che cio' debba essere noto al momento della compilazione: questo e' il polimorfismo, e cioe' essere sicuri che a run-time venga eseguito il metodo definito nella classe appartenente all'oggetto puntato, e non alla sua superclasse.
L'esempio che si fa di solito e' quello della figura geometrica che contiene il metodo area(), che restituisce il valore dell'area. Le classi Triangolo, Quadrato e Cerchio ridefiniscono opportunamente questo metodo. A run-time, se ho un riferimento a una FiguraGeometrica, esso puo' essere utilizzato indifferentemente per un Triangolo, per un Quadrato o per un Cerchio. Il metodo area() eseguito sara' definito a run-time, a seconda che l'oggetto effetivamente referenziato sia un Triangolo, un Quadrato o un Cerchio.
Un ulteriore vantaggio del polimorfismo e' che posso introdurre una nuova figura ad esempio Pentagono, ridefinire opportunamente il metodo area() e inserirla nel progetto, senza aver bisogno di ricompilare tutto il resto, tanto funzionera' correttamente.
Spero di non essere stato eccessvamente lungo. Ciao