Resumen

Comprender la herencia es fundamental para aprovechar todo el potencial de la programación orientada a objetos en C++. A través de este mecanismo, las clases pueden recibir atributos y métodos de otras clases, lo que permite construir jerarquías claras y reutilizar código de forma eficiente. Veamos cómo funciona paso a paso, desde la clase base hasta las especializaciones.

¿Qué es la herencia y por qué es esencial en C++?

La herencia es la capacidad que tienen las clases de recibir características y comportamientos de una o más clases [0:01]. Esto nos permite seguir pensando en entidades relacionadas entre sí. Por ejemplo, una persona puede tener especializaciones como "alumno" o "profesora", y ambas heredan propiedades comunes como nombre o edad.

Otro ejemplo claro es una clase animal que puede derivar en especializaciones como carnívoro, herbívoro u omnívoro [0:38]. Cada una hereda las habilidades generales de ser un animal, pero además incorpora comportamientos únicos.

¿Cómo se construye una clase base en C++?

Antes de heredar, necesitamos una clase sólida desde la cual partir. En el ejemplo mostrado, la clase animal incluye varios conceptos que refuerzan lo aprendido previamente [1:02]:

  • Un constructor que incrementa el conteo de animales y muestra un mensaje en terminal.
  • Un destructor que resta uno al conteo y notifica la eliminación del animal.
  • Un atributo estático privado para llevar el número total de animales.
  • Un método público que retorna ese conteo, manteniendo el atributo encapsulado [1:42].
  • Un método comer que muestra qué alimento consume el animal [2:16].

Al ejecutar este código, se observa el flujo completo: creación del animal con new que invoca al constructor, la ejecución del método comer, la eliminación con delete que dispara el destructor y el conteo regresando a cero [2:47].

¿Cómo se asignan valores por defecto a los atributos?

Si queremos que el animal tenga un alimento predeterminado, basta con asignarle un valor por defecto en la declaración de la variable. Por ejemplo, asignar "carne" como valor inicial hace que al ejecutar comer, el mensaje indique: "este animal está comiendo carne" [3:28].

¿Cómo implementar herencia en C++ paso a paso?

Para crear una clase que herede de otra, se utilizan dos puntos seguidos del nombre de la clase base [3:55]. La sintaxis básica es:

cpp class Herbivoro : public Animal { // especialización };

La palabra public antes del nombre de la clase base es crucial [4:30]. Sin ella, la herencia se comporta como privada por defecto, lo que impide acceder a los miembros heredados desde fuera de la clase.

¿Qué papel juega protected en la herencia?

Cuando un atributo de la clase base está declarado como private, las clases derivadas no pueden acceder a él directamente [5:36]. Aquí entra en juego la palabra reservada protected: funciona de manera similar a private, pero permite que las clases que heredan sí accedan a esos elementos [5:50]. Es el punto intermedio perfecto entre visibilidad total y encapsulamiento estricto.

¿Cómo se utilizan constructores en clases derivadas?

Cuando una clase derivada necesita utilizar el constructor de la clase base, debe indicarlo explícitamente [5:01]:

cpp Herbivoro() : Animal() { alimento = "pasto"; }

Si el constructor de la clase base recibiera argumentos, habría que pasarlos dentro de los paréntesis. En este ejemplo, el constructor de Herbivoro asigna "pasto" como alimento, aprovechando la propiedad alimento definida en Animal.

¿Cómo se crean especializaciones con comportamientos únicos?

Cada clase derivada puede agregar métodos propios que no existen en la clase base. Por ejemplo, la clase Herbivoro incorpora un método pastar [6:18]:

cpp void pastar() { cout << "Este animal está pastando" << endl; }

De la misma forma, se crea una clase Carnivoro con su propio método cazar [7:28]. Al ejecutar el programa completo:

  • El animal genérico come sin saber qué.
  • El herbívoro pasta.
  • El carnívoro caza.
  • El conteo de animales refleja correctamente las creaciones y eliminaciones.

Esta es precisamente la ventaja de la herencia: extender funcionalidades más allá de lo que la clase base ofrece, sin duplicar código [7:50]. Cada especialización conserva todo lo que sabe hacer un animal, pero añade capacidades exclusivas.

Finalmente, surge una pregunta interesante: ¿qué pasa con un omnívoro que puede tanto pastar como cazar? Eso nos lleva al concepto de herencia múltiple, donde una clase hereda de dos o más clases simultáneamente [8:18]. ¿Te gustaría compartir qué otros ejemplos de herencia se te ocurren para modelar con clases en C++?