A mio parere il polimorfismo non è semplicemente una forma di ereditarietà in quanto esistono diverse modalità in cui esso può essere esercitato. Da
wikipedia:
polymorphism is the ability to create a variable, a function, or an object that has more than one form
. Quindi una qualsiasi modalità che mi permette di dare più forme (definizioni) di un metodo (o una classe, o altro) è classificabile come polimorfismo.
Una di queste modalità è l'overriding, la cui definizione è grosso modo quella che hai dato tu: una classe derivata può ridefinire un metodo della classe genitore.
Un'altra modalità di polimorfismo, però, consiste nell'overloading: in questo caso uno stesso metodo presenta signature diverse, quindi ha comportamenti diversi. Es:
//Sintassi Java
public int somma(int a, int b) { ... }
public float somma( float a, float b) { ... }
Un'altra modalità di polimorfismo è data dalla scelta del metodo da utilizzare sulla base del tipo di dato a runtime (binding dinamico o late-binding). Ad esempio:
//Sintassi Java
public class Object {
public String toString() { ...}
}
public class CustomObject {
public String toString() {...}
}
......
Object obj = new CustomObject();
obj.toString();
In questo caso pur essendo obj di tipo Object, il metodo toString che sarà eseguito a runtime sarà quello della classe CustomObject invece che quello di Object. Anche in questo caso, quindi, il metodo "toString" è soggetto a polimorfismo.