¿Qué es el polimorfismo?
En programación, el polimorfismo es la capacidad de un mismo fragmento de código, como una llamada a función o el nombre de un método, de trabajar con valores de tipos distintos, y cada tipo aporta su propio comportamiento. Llamar a shape.area() ejecuta un cálculo distinto para un círculo que para un cuadrado.
Actualizado el 24 de septiembre de 2026
En Python, len("hello") devuelve 5, len([4, 8, 15]) devuelve 3 y len({"a": 1}) devuelve 1. Es un solo nombre de función usado con tres tipos, y cada tipo cuenta a su manera: una cadena cuenta caracteres, una lista cuenta elementos y un diccionario cuenta claves. La palabra viene del griego: poly, muchos, y morph, forma. Una llamada, muchas formas de comportamiento.
Cómo funciona el polimorfismo
El código llama a un método por su nombre, como shape.area(). Cuando esa línea se ejecuta, el lenguaje mira el objeto real y busca area en la propia clase del objeto. Esta búsqueda se llama despacho dinámico (dynamic dispatch), y es lo que permite que una sola línea haga un trabajo distinto para objetos distintos:
Circle 3.14
Square 9
Circle 12.57
Python encuentra el método buscando primero en la clase del objeto y después en sus clases padre, en un orden fijo llamado orden de resolución de métodos (MRO). Si Square no tuviera su propio area(), la búsqueda llegaría a Shape.area() y lanzaría NotImplementedError, una señal de que cada subclase debe aportar el suyo.
El bucle nunca comprueba qué tipo de figura contiene. Para añadir un triángulo, escribes una clase Triangle con su propio area(), y el bucle funciona sin cambios. Sin polimorfismo, el bucle necesitaría una rama if isinstance(...) por cada figura, y habría que editarlo cada vez que apareciera una nueva.
Tipos de polimorfismo
| Tipo | También llamado | Cómo se ve | Cuándo se elige la versión |
|---|---|---|---|
| De subtipos | Polimorfismo en tiempo de ejecución, sobrescritura de métodos | Una subclase sustituye un método de su padre | Mientras el programa se ejecuta |
| Ad hoc | Sobrecarga | Un nombre con varias versiones para distintos tipos de parámetros; también la sobrecarga de operadores | En tiempo de compilación en Java y C++ |
| Paramétrico | Genéricos, plantillas | Un fragmento de código que funciona con cualquier tipo: List<T> en Java, vector<T> en C++ | En tiempo de compilación |
Cuando alguien dice "polimorfismo" en programación orientada a objetos sin más detalle, casi siempre se refiere a la primera fila: el polimorfismo de subtipos mediante sobrescritura.
Python tiene los tres a su manera. La sobrescritura funciona como en el ejemplo de las figuras. Operadores como + son polimorfismo ad hoc. Funciones como max() y sorted() son paramétricas en espíritu: aceptan una lista de números, cadenas o fechas, siempre que los elementos se puedan comparar, y anotaciones de tipo como list[int] o un TypeVar pueden dejarlo explícito.
Polimorfismo en tiempo de compilación y en tiempo de ejecución en Java
Java tiene los dos, y en las entrevistas se pregunta a menudo por la diferencia:
class Animal { String sound() { return "..."; } }
class Dog extends Animal {
@Override String sound() { return "Woof"; }
}
Animal pet = new Dog();
pet.sound(); // "Woof": chosen at run time from the object
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
add(2, 3); // int version, chosen by the compiler
add(2.5, 1.0); // double version
La variable pet tiene el tipo Animal y, sin embargo, se ejecuta la versión de Dog, porque la elección depende del objeto, no de la variable. Los dos métodos add son sobrecarga: el compilador elige uno según los tipos de los argumentos antes de que el programa se ejecute. Las interfaces dan el mismo comportamiento en tiempo de ejecución sin compartir código: cualquier clase que implemente Comparable se puede ordenar con Collections.sort. C++ funciona igual con una diferencia: un método solo tiene despacho en tiempo de ejecución si se declara virtual. Consulta polimorfismo en Java, sobrecarga de métodos y funciones virtuales en C++.
Polimorfismo en Python: duck typing y operadores
Python no exige una clase padre común. Si un objeto tiene el método que llama el código, funciona: "si camina como un pato y hace cuac como un pato, es un pato". Los operadores también son polimórficos. Escribir a + b llama a a.__add__(b), así que tus propias clases pueden admitir +, len() y print():
3 abcd [1, 2]
Vector(11, 22)
5 3 2
La herencia es una forma de conseguir polimorfismo, no un requisito. Vector no hereda de nada especial y, aun así, len() y + lo tratan como un tipo integrado. La documentación de herencia en Python muestra el camino de las subclases.
Errores comunes
Esperar que Python sobrecargue por firma. Un segundo def con el mismo nombre sustituye al primero sin avisar:
Hi Ana Silva
Traceback (most recent call last):
...
TypeError: greet() missing 1 required positional argument: 'last'
Usa un argumento por defecto en su lugar: def greet(first, last="").
Olvidar virtual en C++. Sin él, llamar a un método a través de un puntero a la clase base ejecuta la versión de la base, aunque el objeto sea de una subclase.
Sobrescrituras que cambian el significado. Si area() devuelve el perímetro en una subclase, se rompe todo el código que confía en area(). Una sobrescritura debe cumplir la promesa que hizo el padre; esta regla se conoce como principio de sustitución de Liskov.
Comprobaciones de tipo por todas partes. Una cadena de ramas if type(x) == ... suele ser señal de que cada tipo debería llevar su propio método.
Qué leer después
El polimorfismo trabaja junto con el encapsulamiento, que protege los datos de cada objeto, y la abstracción, que define la interfaz común que implementan los tipos. Practica la sobrescritura en la documentación de clases de Python, o prueba el curso de Java, donde la sobrecarga y la sobrescritura aparecen una al lado de la otra.
Preguntas frecuentes
¿Cuál es un ejemplo de polimorfismo?
+ de Python: 1 + 2 suma números, "ab" + "cd" une cadenas y [1] + [2] une listas. El mismo símbolo funciona con tres tipos, y cada tipo decide qué significa. En el código orientado a objetos, el ejemplo clásico es una lista de figuras en la que cada una responde a area() con su propia fórmula.¿Qué diferencia hay entre polimorfismo y herencia?
¿Qué es el polimorfismo en biología?
¿Python admite la sobrecarga de métodos?
def con el mismo nombre sustituye al primero. El código Python consigue el mismo efecto con argumentos por defecto, *args o functools.singledispatch, que elige una función según el tipo del primer argumento.¿Para qué sirve el polimorfismo?
shape.draw() en cada figura no necesita cambios cuando añades una clase de triángulo; solo escribes la clase nueva. Sin polimorfismo, ese bucle ganaría una rama if nueva por cada tipo.