Dominando la herencia en C#: Conceptos, tipos y código práctico
Herencia en C# explicada
Esta guía cubre los fundamentos de la herencia en C#, sus diversas formas y ejemplos de código prácticos.
La herencia en C# te permite crear una nueva clase que deriva de una existente, formando una relación padre (base) e hijo (derivada). Esta poderosa característica de la Programación Orientada a Objetos (POO) promueve la reutilización de código y organización lógica.
La clase base suministra campos, propiedades y métodos que la clase derivada hereda, permitiendo al hijo extender o personalizar comportamiento mientras mantiene la lógica compartida en un solo lugar.
Cómo declarar herencia en C#
En C#, los dos puntos (:) indican herencia:
class Animal {
// campos y métodos
}
// Dog hereda de Animal
class Dog : Animal {
// campos y métodos de Animal
// campos y métodos de Dog
}
Aquí, Dog extiende Animal, obteniendo acceso a sus miembros. El diagrama siguiente ilustra la relación.

Ejemplo: Herencia básica
using System;
namespace Inheritance {
// Clase base
class Animal {
public string name;
public void Display() {
Console.WriteLine("I am an animal");
}
}
// Clase derivada
class Dog : Animal {
public void GetName() {
Console.WriteLine("My name is " + name);
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.name = "Rohu";
labrador.Display();
labrador.GetName();
Console.ReadLine();
}
}
}
Salida
I am an animal My name is Rohu
En este ejemplo, Dog hereda el campo name y el método Display() de Animal. La clase derivada también puede añadir sus propios miembros, como GetName().
La relación "es-un"
La herencia representa una relación "es-un". Úsala cuando una clase lógicamente es una forma especializada de otra.
- Dog es un Animal
- Apple es una Fruit
- Car es un Vehicle
Estas relaciones justifican derivar Dog de Animal, Apple de Fruit y Car de Vehicle.
Miembros protected en herencia
Cuando un campo o método se declara protected, es accesible dentro de su propia clase y todas las clases derivadas, pero oculto para código externo.
Ejemplo: Usando métodos protected
using System;
namespace Inheritance {
class Animal {
protected void Eat() {
Console.WriteLine("I can eat");
}
}
class Dog : Animal {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
Console.ReadLine();
}
}
}
Salida
I can eat
Como Eat() es protected, la clase Dog puede invocarlo, pero el código fuera de la jerarquía no puede.
Tipos de herencia
La herencia se manifiesta en varios patrones:
1. Herencia simple
Una sola clase derivada hereda de una clase base.

2. Herencia multinivel
Una cadena de herencia donde una clase hereda de una base, luego otra clase hereda de esa derivada.

3. Herencia jerárquica
Múltiples clases derivadas comparten la misma clase base.

4. Herencia múltiple
Aunque C# no soporta heredar de múltiples clases, las interfaces proporcionan una alternativa flexible para lograr comportamiento similar.

5. Herencia híbrida
Una combinación de dos o más tipos de herencia, como multinivel más jerárquica.

Sobrescritura de métodos
Cuando una clase derivada declara un método con la misma firma que un método de clase base marcado virtual, el método derivado puede sobrescribirlo usando override. Esto habilita comportamiento polimórfico.
using System;
namespace Inheritance {
class Animal {
public virtual void Eat() {
Console.WriteLine("I eat food");
}
}
class Dog : Animal {
public override void Eat() {
Console.WriteLine("I eat dog food");
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
}
}
}
Salida
I eat dog food
El método Eat() en Dog sobrescribe al de Animal. La palabra clave virtual permite la sobrescritura, mientras que override señala la sustitución.
Usando la palabra clave base
A veces necesitas invocar la implementación de la clase base desde un método sobrescrito. La palabra clave base facilita esto.
Ejemplo: Llamando métodos base
using System;
namespace Inheritance {
class Animal {
public virtual void Eat() {
Console.WriteLine("Animals eat food.");
}
}
class Dog : Animal {
public override void Eat() {
base.Eat();
Console.WriteLine("Dogs eat dog food.");
}
}
class Program {
static void Main(string[] args) {
Dog labrador = new Dog();
labrador.Eat();
}
}
}
Salida
Animals eat food. Dogs eat dog food.
Aquí, base.Eat() llama a la implementación de Animal antes de ejecutar la lógica de la clase derivada.
Por qué la herencia importa en C#
La herencia permite lógica reutilizable a través de clases relacionadas. Considera formas geométricas donde los cálculos de perímetro comparten una fórmula común.
- Crea una clase base RegularPolygon con método CalculatePerimeter().
- Deriva Square y Rectangle de ella, añadiendo propiedades específicas como Length y Sides.
- Cada clase derivada puede implementar su propio cálculo de área mientras reutiliza la lógica de perímetro.
Ejemplo ilustrativo
using System;
namespace Inheritance {
class RegularPolygon {
public void CalculatePerimeter(int length, int sides) {
int result = length * sides;
Console.WriteLine("Perimeter: " + result);
}
}
class Square : RegularPolygon {
public int Length = 200;
public int Sides = 4;
public void CalculateArea() {
int area = Length * Length;
Console.WriteLine("Area of Square: " + area);
}
}
class Rectangle : RegularPolygon {
public int Length = 100;
public int Breadth = 200;
public int Sides = 4;
public void CalculateArea() {
int area = Length * Breadth;
Console.WriteLine("Area of Rectangle: " + area);
}
}
class Program {
static void Main(string[] args) {
Square s1 = new Square();
s1.CalculateArea();
s1.CalculatePerimeter(s1.Length, s1.Sides);
Rectangle t1 = new Rectangle();
t1.CalculateArea();
t1.CalculatePerimeter(t1.Length, t1.Sides);
}
}
}
Salida
Area of Square: 40000 Perimeter: 800 Area of Rectangle: 20000 Perimeter: 400
Este patrón ilustra cómo la herencia reduce duplicación y mejora mantenibilidad.
Lenguaje C
- Clases y objetos en C#: Fundamentos para POO robusta
- Entendiendo los modificadores de acceso en C#: Public, Private, Protected, Internal y más
- Palabra clave static en C#: Dominando variables, métodos y clases estáticas
- Dominando clases y métodos abstractos en C#: Guía práctica
- Entendiendo clases anidadas en C#: Definición, uso y herencia
- Entendiendo clases y métodos parciales en C#
- Dominando clases y métodos sealed en C#: Cuándo usarlos, ejemplos claros y mejora de seguridad y rendimiento
- Entendiendo el Polimorfismo en C++: Guía Práctica
- Dominando la Abstracción de Datos en C++: Simplifica el Diseño con Separación Interfaz-Implementación
- Estructura de Programa C#: Componentes Principales y Ejemplo Hello World
- Fundamentos de C#: Sintaxis Básica y Conceptos de POO