CSharp
Tutorial CSharp: Polimorfismo
CSharp polimorfismo: técnicas y ejemplos. Aprende técnicas de polimorfismo en CSharp con ejemplos prácticos y detallados.
El polimorfismo es un concepto fundamental de la programación orientada a objetos. En C#, este concepto permite a las clases derivadas compartir comportamientos con las clases base. En resumen, el polimorfismo permite tratar objetos de una clase derivada como si fueran objetos de su clase base. Este concepto es muy útil cuando se necesita trabajar con grupos de objetos relacionados de manera genérica.
El polimorfismo en C# se logra de dos maneras:
- A través de la herencia, donde una clase derivada puede heredar miembros de la clase base.
- A través de las interfaces, que permiten que las clases no relacionadas tengan comportamientos comunes.
Ejemplo de Polimorfismo en C# a través de la Herencia
Un ejemplo clásico para ilustrar el polimorfismo es una clase base Animal
y dos clases derivadas Perro
y Gato
.
public class Animal
{
public virtual void HacerSonido()
{
Console.WriteLine("El animal hace un sonido");
}
}
public class Perro : Animal
{
public override void HacerSonido()
{
Console.WriteLine("El perro ladra");
}
}
public class Gato : Animal
{
public override void HacerSonido()
{
Console.WriteLine("El gato maúlla");
}
}
En este ejemplo, la clase Animal
tiene un método HacerSonido()
. Las clases Perro
y Gato
heredan de la clase Animal
y sobrescriben el método HacerSonido()
. Para ello, el método en la clase padre debe ser declarado como virtual
, que indica que puede ser sobreescrito, y entonces el método en la clase hija ser marcado como override
, para sobreescribirlo.
Ahora, se puede referir a un objeto Perro
o Gato
como si fuera un objeto Animal
y llamar al método HacerSonido()
. C# determinará en tiempo de ejecución qué versión del método debe ser llamada, dependiendo del tipo real del objeto.
Animal miAnimal = new Perro();
miAnimal.HacerSonido(); // Output: "El perro ladra"
miAnimal = new Gato();
miAnimal.HacerSonido(); // Output: "El gato maúlla"
Específicamente, cuando se llama a un método desde alguna clase y hay varias clases derivadas, la búsqueda de la declaración del método sigue una secuencia específica. Se realiza una búsqueda en profundidad primero (depth-first search) a través de la jerarquía de herencia. El orden de búsqueda se puede entender de la siguiente manera:
Búsqueda en la clase actual: Primero, se busca el método en la clase desde la cual se realiza la llamada. Si el método se encuentra en esta clase, la búsqueda se detiene y se utiliza esta definición.
Búsqueda en la clase base: Si el método no se encuentra en la clase actual, la búsqueda continúa en la clase base. Esto se repite de manera recursiva si tampoco se encuentra en la clase base, buscando en cada clase inmediatamente superior hasta que se encuentra el método o hasta que se hayan revisado todas las clases relacionadas y no se encuentre, lanzando un error en tiempo de compilación.
Ejemplo de Polimorfismo en C# a través de Interfaces
Las interfaces proporcionan una manera de lograr el polimorfismo entre clases que no están relacionadas a través de la herencia.
A continuación, se define una interfaz IVolador
con un método Volar()
. Dos clases, Pajaro
y Avion
, implementan esta interfaz.
public interface IVolador
{
void Volar();
}
public class Pajaro : IVolador
{
public void Volar()
{
Console.WriteLine("El pájaro vuela");
}
}
public class Avion : IVolador
{
public void Volar()
{
Console.WriteLine("El avión vuela");
}
}
Aunque Pajaro
y Avion
no están relacionados por herencia, ambos implementan la interfaz IVolador
. Esto significa que pueden ser tratados de manera genérica como objetos IVolador
.
IVolador miVolador = new Pajaro();
miVolador.Volar(); // Output: "El pájaro vuela"
miVolador = new Avion();
miVolador.Volar(); // Output: "El avión vuela"
En ambos casos, C# utiliza el polimorfismo para determinar en tiempo de ejecución qué versión del método Volar()
debe ser llamada.
Polimorfirsmo Estático y Dinámico
En el contexto de la programación orientada a objetos, el polimorfismo se divide en dos categorías principales: el polimorfismo estático (también conocido como polimorfismo en tiempo de compilación) y el polimorfismo dinámico (también conocido como polimorfismo en tiempo de ejecución).
Polimorfismo Estático
El polimorfismo estático, también conocido como sobrecarga de métodos, ocurre en tiempo de compilación. En este caso, el polimorfismo se logra mediante la creación de varios métodos con el mismo nombre pero con diferentes firmas (es decir, diferentes tipos de parámetros o número de parámetros) en la misma clase. Cuando se llama a un método, el compilador determina el método específico a utilizar a través de la coincidencia de los argumentos con las firmas de los métodos.
public class Calculadora
{
public int Sumar(int a, int b)
{
return a + b;
}
public float Sumar(float a, float b)
{
return a + b;
}
public double Sumar(double a, double b)
{
return a + b;
}
}
En este ejemplo, el método Sumar
está sobrecargado con diferentes firmas de método: Sumar(int, int)
, Sumar(float, float)
y Sumar(double, double)
. El compilador determinará cuál de estos métodos llamar en función de los tipos de argumentos utilizados.
Polimorfismo Dinámico
El polimorfismo dinámico, también conocido como anulación de métodos, ocurre en tiempo de ejecución. En este caso, el polimorfismo se logra mediante la creación de un método en la clase base y la redefinición de este mismo método en la clase derivada. Cuando se llama a un método, la versión específica del método a utilizar se determina en tiempo de ejecución, basándose en el objeto que realiza la llamada.
public class Animal
{
public virtual void HacerSonido()
{
Console.WriteLine("El animal hace un sonido");
}
}
public class Perro : Animal
{
public override void HacerSonido()
{
Console.WriteLine("El perro ladra");
}
}
public class Gato : Animal
{
public override void HacerSonido()
{
Console.WriteLine("El gato maúlla");
}
}
En este ejemplo, el método HacerSonido
se declara en la clase base Animal
y luego se redefinido en las clases derivadas Perro
y Gato
. En tiempo de ejecución, C# determinará cuál versión del método HacerSonido
debe llamarse basándose en si el objeto es de tipo Perro
o Gato
.
Por tanto, el polimorfismo estático y el polimorfismo dinámico son dos caras de la misma moneda. Ambos son esenciales para lograr la flexibilidad y la reutilización en la programación orientada a objetos.
En resumen, el polimorfismo es una poderosa herramienta en C# y la programación orientada a objetos en general, ya que permite tratar objetos de diferentes clases de una manera genérica, al tiempo que se mantiene la capacidad de invocar comportamientos específicos de la clase.
Ejercicios de esta lección Polimorfismo
Evalúa tus conocimientos de esta lección Polimorfismo con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Excepciones
Operadores
Control de flujo
Polimorfismo
Funciones
Arrays y listas
Variables y constantes
Diccionarios
Variables y constantes
Constructores y destructores
Clases y encapsulación
Polimorfismo
Eventos
Operadores
LINQ
Lambdas
Excepciones
Objetos
Conjuntos, colas y pilas
Tipos de datos
Tipos de datos
Tareas
Diccionarios en C#
Funciones
Funciones
Constructores y destructores
Constructores y destructores
Delegados
Herencia C Sharp
Uso de consultas LINQ
Excepciones
Lambdas
Conjuntos, colas y pilas
Introducción a C#
Diccionarios
Uso de async y await
Tipos de datos
Clases y objetos
Creación de proyecto C#
Herencia
Uso de consultas LINQ
Arrays y listas
Herencia de clases
Clases y encapsulación
Operadores
Arrays y listas
Uso de async y await
Control de flujo
OOP en C Sharp
CRUD en C# de modelo Customer sobre una lista
Objetos
Control de flujo
Tareas
Variables y constantes
Delegados
Eventos
Todas las lecciones de CSharp
Accede a todas las lecciones de CSharp y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A C#
Sintaxis
Creación De Proyecto C#
Sintaxis
Variables Y Constantes
Sintaxis
Tipos De Datos
Sintaxis
Operadores
Sintaxis
Control De Flujo
Sintaxis
Funciones
Sintaxis
Clases Y Encapsulación
Programación Orientada A Objetos
Objetos
Programación Orientada A Objetos
Constructores Y Destructores
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Excepciones
Excepciones
Arrays Y Listas
Colecciones Y Linq
Diccionarios
Colecciones Y Linq
Conjuntos, Colas Y Pilas
Colecciones Y Linq
Uso De Consultas Linq
Colecciones Y Linq
Delegados
Programación Asíncrona
Eventos
Programación Asíncrona
Lambdas
Programación Asíncrona
Uso De Async Y Await
Programación Asíncrona
Tareas
Programación Asíncrona
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el concepto de polimorfismo en C# y su importancia en la programación orientada a objetos.
- Aprender a implementar el polimorfismo a través de la herencia, permitiendo que las clases derivadas sobrescriban métodos de la clase base.
- Conocer cómo implementar el polimorfismo mediante el uso de interfaces, permitiendo que clases no relacionadas tengan comportamientos comunes.
- Familiarizarse con los conceptos de polimorfismo estático y dinámico, y cómo se logran en C# mediante la sobrecarga de métodos y la anulación de métodos, respectivamente.
- Entender cómo el polimorfismo mejora la flexibilidad y la reutilización de código en la programación orientada a objetos.