Saludos, como comenté en el post anterior de Clases en C++ el modificador de acceso protegido o protected lo revisaremos ahora, pero antes de entender sobre el mismo vamos a revisar de manera rápida lo que es la herencia en POO.

Herencia

Vamos a imaginar que tenemos una clase llamada Perro en nuestro programa, un perro tiene nombre, edad y un dueño.


class Dog {

private:
    int age;
    char *name, *ownersName;

public:
    // Contructor
    Dog(int age, char *name, char *ownersName) {
        this->age = age;
        this->name = name;
        this->ownersName;
    }
};

Ahora vamos a imaginar que tenemos una clase llamada Caballo en nuestro programa, dicho caballo tiene edad y peso;

class Horse {

private:
    int age;
    float weight;

public:
    // Constructor
    Horse(int age, float weight) {
        this->age=age;
        this->weight = weight;
    }
};

Hasta aquí todo está bien, son dos clases diferentes que pertenecen a dos animales diferentes, espera espera, dije "dos animales". Ya que ambos son animales deben tener cosas en común, podríamos tener solo una clase Animal, pero el problema es que no todos los animales tienen las mismas características (Ejem. Un humano no tiene plumas). Es aquí donde la herencia viene a ayudarnos.

De la misma manera que en los seres vivos la herencia nos hace tener ciertas características traídas de nuestros antecesores (ojos marrones o azules, cabello rizado o liso, etc.) En OOP la herencia nos permite crear clases que tienen características en común con una clase padre, para ello lo haremos de la siquiente manera.

class Animal {
/**
* El modificador de acceso protegido permite que todas las clases "hijas",
* es decir todas las clases que hereden de esta clase puedan acceder a sus
* variables o funciones pero estas no puede ser accedidas desde el exterior
*/
protected:
    int age;

public:
    /**
    * Otra forma de crear un costructor es  usar
    * :variableClase(parametroConstructor)
    * :age(age) -> el primer age es la variable
    * de la clase y el segundo es el parametro del constructor
    */
    Animal(int age): age(age) {
        cout << "Constructor called for Animal object" << endl;
    }

    ~Animal() {
        cout << "Destructor called for Animal Object" << endl;
    }
};

Perfecto tenemos una clase animal con una variable de edad que será la que compartan las clases hijas.

Para heredar la clase Animal hacia otra clase lo haremos de la siguiente manera:

class Gato: public Animal{...}

Veamos el siguiente ejemplo.

// Clase Dog
class Dog: public Animal {

private:
    char *name, *ownersName;

public:
    /**
    * Para pasar la edad hacia la clase Animal
    * a traves del constructor de nuestra clase Dog
    * usamos tenemos que recibir la edad como parametro
    * en el constructor y mandarlo hacia animal utilizando
    * :Animal(parametroEdad)
    */
    Dog(int age, char *name, char *ownersName): Animal(age) {
        this->name = name;
        this->ownersName = ownersName;
        cout << "Constructor called for Dog object" << endl;
    }

    ~Dog() {
        cout << "Destructor called for Dog object" << endl;
    }

    // Funciones públicas
    void printDogInfo() {
        cout << "Name is: " << this->name << " has " << this->age 
        << " years old and its owner is: " << this->ownersName << endl;
    }
};

// Clase Horse
class Horse: public Animal {

private:
    float weight;

public:
    // Constructor & Destructor
    Horse(int age, float weight): Animal(age) {
        this->weight = weight;
        cout << "Constructor called for Horse object" << endl;
    }

    ~Horse() {
        cout << "Destructor called for Horse object" << endl;
    }

    // Funciones públicas
    void printHorseInfo() {
        cout << "The horse has: " << this->age << " years old and weights: "
        << this->weight << " kilograms" << endl;
    }
};

Ahora para poder utilizar estas clases en nuestro main lo haremos como con cualquier clase.

int main() {

    // Variables para clase Dog
    char dogName[10] = "Max";
    char ownersName[10] = "Jon";
    int dogAge = 1;

    // Nueva instancia de la clase Dog y llamada a su función de impresión
    Dog *dog = new Dog(dogAge, dogName, ownersName);
    dog->printDogInfo();
'   delete dog; // Liberamos a la memoria de la clase Dog

    // Variables para clase Horse
    int horseAge = 4;
    float horseWeight = 312.953;

    // Nueva instancia de la clase Horse y llamada a su función de impresión
    Horse *horse = new Horse(horseAge, horseWeight);
    horse->printHorseInfo();
'   delete horse; // Liberamos a la memoria de la clase Horse
    return 0;

Después de compilar nuestro programa y correrlo la respuesta que obtendremos será la siguiente:

Constructor called for Animal object                                                                                                                                                                                                                                              
Constructor called for Dog object                                                                                                                                                                                                                                                 
Name is: Max has 1 years old and its owner is: Jon                                                                                                                                                                                                                                
Destructor called for Dog object                                                                                                                                                                                                                                                  
Destructor called for Animal Object                                                                                                      
Constructor called for Animal object                                                                                                     
Constructor called for Horse object                                                                                                      
The horse has: 4 years old and weights: 312.953 kilograms                                                                                 
Destructor called for Horse object                                                                                                       
Destructor called for Animal Object

Como podemos ver al momento de iniciar la clase "Dog" se llama a su clase padre y primero se inicia la clase "Animal", de manera invertida cuando vamos a liberar la memoria, primero llamamos al destructor de la clase "Dog" y luego al de la clase "Animal"

El código de este ejemplo lo pueden ver en:
https://github.com/nano-bytes/cpp-compilation/blob/master/classes/main-inheritance.cpp

Hasta otra
Happy Hacking!

Última modificación: 16/02/2021

Autor