Exploración del polimorfismo basado en herencia
El polimorfismo basado en herencia se basa en una jerarquía de clases donde las clases derivadas heredan el comportamiento y las propiedades de una clase base. La relación de herencia permite tratar objetos de clases derivadas como objetos de la clase base. La capacidad de tratar objetos de clase derivados como objetos de clase base permite escribir código que funcione con varios tipos de objetos sin conocer el tipo específico en tiempo de compilación.
En el ejemplo de código siguiente se muestra el polimorfismo basado en herencia en C#:
// Base class
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound.");
}
}
// Derived class Dog
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks.");
}
}
// Derived class Cat
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cat meows.");
}
}
// Derived class Cow
public class Cow : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cow moos.");
}
}
class Program
{
static void Main()
{
// Create an array of Animal objects
Animal[] animals = new Animal[3];
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Cow();
animals[0] = animal1;
animals[1] = animal2;
animals[2] = animal3;
// Demonstrate polymorphism
foreach (Animal animal in animals)
{
animal.MakeSound();
}
}
}
En este código de ejemplo, observe que la clase Program crea una matriz de objetos Animal y asigna instancias de Dog, Cat y Cow a los elementos de matriz. Se llama al método MakeSound en cada objeto de la matriz, que muestra el polimorfismo. El método MakeSound se invalida en las clases derivadas para proporcionar un comportamiento específico para cada tipo animal.
Convertir un objeto de una clase base en una clase derivada
La conversión en C# es el proceso de convertir un objeto de un tipo a otro tipo. La conversión se usa a menudo al implementar polimorfismo mediante jerarquías de herencia, donde tiene una clase base y una o varias clases derivadas.
Hay dos tipos principales de conversión:
Conversión implícita: esto se produce automáticamente al convertir una clase derivada en una clase base. Es seguro porque cada instancia de una clase derivada también es una instancia de la clase base.
BankAccount account = new CheckingAccount();Conversión explícita: esto requiere un operador de conversión y se usa al convertir una clase base en una clase derivada. No siempre es seguro porque no todas las instancias de una clase base son una instancia de la clase derivada.
CheckingAccount checkingAccount = (CheckingAccount)account;
Convertir objetos mediante las palabras clave is y as
En C#, puede convertir objetos usando las palabras clave is y as. Estas palabras clave proporcionan una manera segura de comprobar el tipo de un objeto antes de convertirlo a otro tipo. Estas son algunas formas comunes de convertir objetos en C#:
Uso de la palabra clave
iscon coincidencia de patrones:if (account is CheckingAccount checkingAccount) { // Use checkingAccount as a CheckingAccount }- Esta sintaxis comprueba si
accountes de tipoCheckingAccount. - Si la comprobación se realiza correctamente, convierte
accountenCheckingAccounty la asigna a la variablecheckingAccount. - Este enfoque es conciso y seguro, ya que combina la comprobación de tipos y la conversión en un paso.
- Esta sintaxis comprueba si
Con la palabra clave
isseguida de la conversión explícita:if (account is CheckingAccount) { CheckingAccount checkingAccount = (CheckingAccount)account; // Use checkingAccount as a CheckingAccount }- Esta sintaxis comprueba si
accountes de tipoCheckingAccount. - Si la comprobación se realiza correctamente, convierte explícitamente
accountenCheckingAccounty la asigna a la variablecheckingAccount. - Este enfoque es más detallado que la sintaxis de coincidencia de patrones, pero proporciona más control sobre el proceso de conversión.
- Esta sintaxis comprueba si
Con la palabra clave
as:CheckingAccount checkingAccount = account as CheckingAccount; if (checkingAccount != null) { // Use checkingAccount as a CheckingAccount }- Esta sintaxis intenta convertir
accountenCheckingAccounty asigna el resultado acheckingAccount. - Si la conversión es correcta,
checkingAccountcontiene el objeto de conversión; de lo contrario, es null. - Este enfoque es útil cuando desea comprobar el resultado de la conversión antes de usar el objeto de conversión. Por ejemplo, si desea evitar excepciones y controlar el caso de error correctamente.
- Esta sintaxis intenta convertir
Al implementar la conversión, tenga en cuenta las siguientes directrices:
- Uso de la coincidencia de patrones con
is: combina la comprobación de tipos y la conversión en un paso. - Uso de la palabra clave
iscon conversión explícita: separa la comprobación de tipos y convierte en dos pasos, lo que proporciona más control sobre el proceso de conversión. - Uso de la palabra clave
as: los intentos de conversión y controlan el error correctamente devolviendo null.
- Uso de la coincidencia de patrones con
Comprender estas técnicas de conversión es esencial para trabajar con polimorfismo y herencia en C#.
Evitar problemas comunes al implementar polimorfismo
Cuando el objetivo es el polimorfismo basado en herencia, estas son algunas cosas que se deben evitar y algunas cosas para garantizar:
Evite usar clases y métodos sellados: las clases y los métodos sellados no se pueden heredar ni invalidar, lo que limita la capacidad de usar polimorfismo. Si sella una clase o un método, se evita una mayor extensión y personalización. Por ejemplo:
public sealed class BankAccount { } // This class can't be inheritedEvite el uso excesivo de métodos estáticos. Los métodos estáticos pertenecen a la propia clase en lugar de a una instancia de la clase. No se pueden invalidar, lo que significa que no participan en el polimorfismo.
public static void PrintMessage() { } // This method can't be overriddenEvite emparejamiento estricto. El acoplamiento estricto se produce cuando las clases o componentes de un sistema dependen en gran medida entre sí. Esto significa que los cambios de una clase pueden afectar directamente a otras clases, lo que hace que el sistema sea menos flexible y más difícil de mantener. El acoplamiento estricto puede provocar dificultades en las pruebas, la extensión y la modificación del código.
public class BankAccount { public void TransferFunds(SavingsAccount savingsAccount) { // Tight coupling with SavingsAccount } }Evite usar la palabra clave "new" sin una buena razón. La palabra clave "new" oculta el método de clase base en la clase derivada, lo que puede provocar confusión y comportamiento inesperado. Use solo la palabra clave 'new' cuando quiera ocultar el método de clase base intencionadamente.
public class Dog : Animal { public new void MakeSound() // Hides the base class method. Better to use 'override' { Console.WriteLine("The dog barks."); } }Asegúrese de que las firmas de método sean coherentes. Asegúrese de que los métodos invalidados en las clases derivadas tengan la misma firma que el método de clase base. Si se cambia la firma del método, se ocultará el método en lugar de invalidarla.
public class Animal { public virtual void MakeSound(string sound) { Console.WriteLine("The animal makes a sound."); } } public class Dog : Animal { // Method signature doesn't match the base class public override void MakeSound() { Console.WriteLine("The dog barks."); } }
Resumen
El polimorfismo basado en herencia en C# permite crear una jerarquía de clases donde las clases derivadas heredan el comportamiento y las propiedades de una clase base. Este mecanismo de herencia permite tratar objetos de clases derivadas como objetos de la clase base. La capacidad de tratar objetos de clase derivadas como miembros de una clase base permite escribir código que funcione con varios tipos de objetos sin conocer el tipo específico en tiempo de compilación. Al comprender las técnicas de conversión, evitar los problemas comunes y seguir los procedimientos recomendados, puede implementar de forma eficaz el polimorfismo en las aplicaciones de C#.