csharp-herencia

Qué es y cómo usar la herencia en C#

La herencia de clases es un mecanismo que permite a una clase derivar de otra clase. Esto significa que “heredará” todos sus campos, propiedades y métodos.

La clase de la cual se hereda se conoce como clase base (o clase padre). Por otro lado, la clase que hereda se llama clase derivada (o clase hija).

Implementación de la herencia en C#

La herencia en C# se implementa utilizando la sintaxis de dos puntos (:) seguida del nombre de la clase base.

public class ClaseBase
{
    // Miembros de la clase base
}

public class ClaseDerivada : ClaseBase
{
    // Miembros adicionales de la clase derivada
}

Ejemplo básico

public class Animal
{
    public void Comer()
    {
        Console.WriteLine("El animal está comiendo.");
    }
}

public class Perro : Animal
{
    public void Ladrar()
    {
        Console.WriteLine("El perro está ladrando.");
    }
}

// Uso
Perro miPerro = new Perro();
miPerro.Comer();  // Heredado de Animal
miPerro.Ladrar(); // Definido en Perro

En este ejemplo,

  • La clase Perro hereda de la clase Animal
  • Esto significa que Perro tiene acceso a los métodos de Animal, como Comer
  • Además de sus propios métodos como Ladrar.

Sobrescritura de métodos

Las clases derivadas pueden sobrescribir métodos de la clase base utilizando las palabras clave virtual en la clase base y override en la clase derivada.

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.");
    }
}

// Uso
Animal miAnimal = new Animal();
miAnimal.HacerSonido(); // Salida: El animal hace un sonido.

Perro miPerro = new Perro();
miPerro.HacerSonido(); // Salida: El perro ladra.

En este ejemplo, Perro sobrescribe el método HacerSonido de Animal para proporcionar una implementación específica.

Palabra clave base

La palabra clave base se utiliza para acceder a miembros de la clase base desde una clase derivada. Esto es útil para invocar constructores, métodos y propiedades de la clase base.

public class Animal
{
    public string Nombre { get; set; }

    public Animal(string nombre)
    {
        Nombre = nombre;
    }

    public virtual void HacerSonido()
    {
        Console.WriteLine("El animal hace un sonido.");
    }
}

public class Perro : Animal
{
    public Perro(string nombre) : base(nombre)
    {
    }

    public override void HacerSonido()
    {
        base.HacerSonido(); // Invoca el método de la clase base
        Console.WriteLine("El perro ladra.");
    }
}

// Uso
Perro miPerro = new Perro("Fido");
miPerro.HacerSonido();
// Salida:
// El animal hace un sonido.
// El perro ladra.

Constructores en clases derivadas

Cuando se crea una instancia de una clase derivada, el constructor de la clase base se invoca automáticamente antes que el constructor de la clase derivada.

Se puede especificar explícitamente qué constructor de la clase base se debe llamar usando la palabra clave base.

public class Animal
{
    public string Nombre { get; set; }

    public Animal(string nombre)
    {
        Nombre = nombre;
    }
}

public class Perro : Animal
{
    public string Raza { get; set; }

    public Perro(string nombre, string raza) : base(nombre)
    {
        Raza = raza;
    }
}

// Uso
Perro miPerro = new Perro("Fido", "Labrador");
Console.WriteLine($"Nombre: {miPerro.Nombre}, Raza: {miPerro.Raza}");
// Salida: Nombre: Fido, Raza: Labrador

Herencia y polimorfismo

El polimorfismo es otra característica clave de la POO que se complementa con la herencia. Permite que una clase derivada sea tratada como una instancia de su clase base. Esto permite la sustituir objetos, pero que a la vez mantienen los métodos sobreescritos.

public class Gato : Animal
{
    public override void HacerSonido()
    {
        Console.WriteLine("El gato maúlla.");
    }
}

// Uso
Animal miAnimal;

miAnimal = new Perro("Fido");
miAnimal.HacerSonido(); // Salida: El perro ladra.

miAnimal = new Gato("Mishi");
miAnimal.HacerSonido(); // Salida: El gato maúlla.

En este ejemplo,

  • miAnimal puede referirse a un Perro o a un Gato
  • Se invoca al método HacerSonido apropiado según el tipo de instancia (en tiempo de ejecución)